@@ -116,21 +116,24 @@ impl DeploymentHash {
116
116
pub fn new ( s : impl Into < String > ) -> Result < Self , String > {
117
117
let s = s. into ( ) ;
118
118
119
- // Enforce length limit
120
- if s. len ( ) > 46 {
121
- return Err ( s) ;
122
- }
119
+ // This section is being temporarily commented out. This is to allow file link resolver to work
120
+ // TODO(krishna): Figure out how to do this better or remove this check
123
121
124
- // Check that the ID contains only allowed characters.
125
- if !s . chars ( ) . all ( |c| c . is_ascii_alphanumeric ( ) || c == '_' ) {
126
- return Err ( s) ;
127
- }
122
+ // // Enforce length limit
123
+ // if s.len() > 46 {
124
+ // return Err(s);
125
+ // }
128
126
129
- // Allow only deployment id's for 'real' subgraphs, not the old
130
- // metadata subgraph.
131
- if s == "subgraphs" {
132
- return Err ( s) ;
133
- }
127
+ // // Check that the ID contains only allowed characters.
128
+ // if !s.chars().all(|c| c.is_ascii_alphanumeric() || c == '_') {
129
+ // return Err(s);
130
+ // }
131
+
132
+ // // Allow only deployment id's for 'real' subgraphs, not the old
133
+ // // metadata subgraph.
134
+ // if s == "subgraphs" {
135
+ // return Err(s);
136
+ // }
134
137
135
138
Ok ( DeploymentHash ( s) )
136
139
}
@@ -397,12 +400,65 @@ impl From<HashMap<Word, Value>> for DataSourceContext {
397
400
}
398
401
399
402
/// IPLD link.
400
- #[ derive( Clone , Debug , Default , Hash , Eq , PartialEq , Deserialize ) ]
403
+ #[ derive( Clone , Debug , Default , Hash , Eq , PartialEq ) ]
401
404
pub struct Link {
402
- #[ serde( rename = "/" ) ]
403
405
pub link : String ,
404
406
}
405
407
408
+ /// Custom deserializer for Link
409
+ /// This handles both formats:
410
+ /// 1. Simple string: "schema.graphql" or "subgraph.yaml" which is used in [`FileLinkResolver`]
411
+ /// FileLinkResolver is used in local development environments
412
+ /// 2. IPLD format: { "/": "Qm..." } which is used in [`IpfsLinkResolver`]
413
+ impl < ' de > de:: Deserialize < ' de > for Link {
414
+ fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
415
+ where
416
+ D : de:: Deserializer < ' de > ,
417
+ {
418
+ struct LinkVisitor ;
419
+
420
+ impl < ' de > de:: Visitor < ' de > for LinkVisitor {
421
+ type Value = Link ;
422
+
423
+ fn expecting ( & self , formatter : & mut fmt:: Formatter ) -> fmt:: Result {
424
+ formatter. write_str ( "string or map with '/' key" )
425
+ }
426
+
427
+ fn visit_str < E > ( self , value : & str ) -> Result < Link , E >
428
+ where
429
+ E : de:: Error ,
430
+ {
431
+ Ok ( Link {
432
+ link : value. to_string ( ) ,
433
+ } )
434
+ }
435
+
436
+ fn visit_map < A > ( self , mut map : A ) -> Result < Link , A :: Error >
437
+ where
438
+ A : de:: MapAccess < ' de > ,
439
+ {
440
+ let mut link = None ;
441
+
442
+ while let Some ( key) = map. next_key :: < String > ( ) ? {
443
+ if key == "/" {
444
+ if link. is_some ( ) {
445
+ return Err ( de:: Error :: duplicate_field ( "/" ) ) ;
446
+ }
447
+ link = Some ( map. next_value ( ) ?) ;
448
+ } else {
449
+ return Err ( de:: Error :: unknown_field ( & key, & [ "/" ] ) ) ;
450
+ }
451
+ }
452
+
453
+ link. map ( |l : String | Link { link : l } )
454
+ . ok_or_else ( || de:: Error :: missing_field ( "/" ) )
455
+ }
456
+ }
457
+
458
+ deserializer. deserialize_any ( LinkVisitor )
459
+ }
460
+ }
461
+
406
462
impl < S : ToString > From < S > for Link {
407
463
fn from ( s : S ) -> Self {
408
464
Self {
0 commit comments