@@ -384,7 +384,12 @@ impl<'de> de::SeqAccess<'de> for ConfigSeqAccess {
384
384
{
385
385
match self . list_iter . next ( ) {
386
386
// TODO: add `def` to error?
387
- Some ( ( value, _def) ) => seed. deserialize ( value. into_deserializer ( ) ) . map ( Some ) ,
387
+ Some ( ( value, def) ) => {
388
+ // This might be a String or a Value<String>.
389
+ // ValueDeserializer will handle figuring out which one it is.
390
+ let maybe_value_de = ValueDeserializer :: new_with_string ( value, def) ;
391
+ seed. deserialize ( maybe_value_de) . map ( Some )
392
+ }
388
393
None => Ok ( None ) ,
389
394
}
390
395
}
@@ -400,7 +405,17 @@ impl<'de> de::SeqAccess<'de> for ConfigSeqAccess {
400
405
struct ValueDeserializer < ' config > {
401
406
hits : u32 ,
402
407
definition : Definition ,
403
- de : Deserializer < ' config > ,
408
+ /// The deserializer, used to actually deserialize a Value struct.
409
+ /// This is `None` if deserializing a string.
410
+ de : Option < Deserializer < ' config > > ,
411
+ /// A string value to deserialize.
412
+ ///
413
+ /// This is used for situations where you can't address a string via a
414
+ /// TOML key, such as a string inside an array. The `ConfigSeqAccess`
415
+ /// doesn't know if the type it should deserialize to is a `String` or
416
+ /// `Value<String>`, so `ValueDeserializer` needs to be able to handle
417
+ /// both.
418
+ str_value : Option < String > ,
404
419
}
405
420
406
421
impl < ' config > ValueDeserializer < ' config > {
@@ -428,9 +443,19 @@ impl<'config> ValueDeserializer<'config> {
428
443
Ok ( ValueDeserializer {
429
444
hits : 0 ,
430
445
definition,
431
- de,
446
+ de : Some ( de) ,
447
+ str_value : None ,
432
448
} )
433
449
}
450
+
451
+ fn new_with_string ( s : String , definition : Definition ) -> ValueDeserializer < ' config > {
452
+ ValueDeserializer {
453
+ hits : 0 ,
454
+ definition,
455
+ de : None ,
456
+ str_value : Some ( s) ,
457
+ }
458
+ }
434
459
}
435
460
436
461
impl < ' de , ' config > de:: MapAccess < ' de > for ValueDeserializer < ' config > {
@@ -459,9 +484,14 @@ impl<'de, 'config> de::MapAccess<'de> for ValueDeserializer<'config> {
459
484
// If this is the first time around we deserialize the `value` field
460
485
// which is the actual deserializer
461
486
if self . hits == 1 {
462
- return seed
463
- . deserialize ( self . de . clone ( ) )
464
- . map_err ( |e| e. with_key_context ( & self . de . key , self . definition . clone ( ) ) ) ;
487
+ if let Some ( de) = & self . de {
488
+ return seed
489
+ . deserialize ( de. clone ( ) )
490
+ . map_err ( |e| e. with_key_context ( & de. key , self . definition . clone ( ) ) ) ;
491
+ } else {
492
+ return seed
493
+ . deserialize ( self . str_value . as_ref ( ) . unwrap ( ) . clone ( ) . into_deserializer ( ) ) ;
494
+ }
465
495
}
466
496
467
497
// ... otherwise we're deserializing the `definition` field, so we need
@@ -484,6 +514,71 @@ impl<'de, 'config> de::MapAccess<'de> for ValueDeserializer<'config> {
484
514
}
485
515
}
486
516
517
+ // Deserializer is only implemented to handle deserializing a String inside a
518
+ // sequence (like `Vec<String>` or `Vec<Value<String>>`). `Value<String>` is
519
+ // handled by deserialize_struct, and the plain `String` is handled by all the
520
+ // other functions here.
521
+ impl < ' de , ' config > de:: Deserializer < ' de > for ValueDeserializer < ' config > {
522
+ type Error = ConfigError ;
523
+
524
+ fn deserialize_str < V > ( self , visitor : V ) -> Result < V :: Value , Self :: Error >
525
+ where
526
+ V : de:: Visitor < ' de > ,
527
+ {
528
+ visitor. visit_str ( & self . str_value . expect ( "string expected" ) )
529
+ }
530
+
531
+ fn deserialize_string < V > ( self , visitor : V ) -> Result < V :: Value , Self :: Error >
532
+ where
533
+ V : de:: Visitor < ' de > ,
534
+ {
535
+ visitor. visit_string ( self . str_value . expect ( "string expected" ) )
536
+ }
537
+
538
+ fn deserialize_struct < V > (
539
+ self ,
540
+ name : & ' static str ,
541
+ fields : & ' static [ & ' static str ] ,
542
+ visitor : V ,
543
+ ) -> Result < V :: Value , Self :: Error >
544
+ where
545
+ V : de:: Visitor < ' de > ,
546
+ {
547
+ // Match on the magical struct name/field names that are passed in to
548
+ // detect when we're deserializing `Value<T>`.
549
+ //
550
+ // See more comments in `value.rs` for the protocol used here.
551
+ if name == value:: NAME && fields == value:: FIELDS {
552
+ return visitor. visit_map ( self ) ;
553
+ }
554
+ unimplemented ! ( "only strings and Value can be deserialized from a sequence" ) ;
555
+ }
556
+
557
+ fn deserialize_any < V > ( self , visitor : V ) -> Result < V :: Value , Self :: Error >
558
+ where
559
+ V : de:: Visitor < ' de > ,
560
+ {
561
+ visitor. visit_string ( self . str_value . expect ( "string expected" ) )
562
+ }
563
+
564
+ fn deserialize_ignored_any < V > ( self , visitor : V ) -> Result < V :: Value , Self :: Error >
565
+ where
566
+ V : de:: Visitor < ' de > ,
567
+ {
568
+ visitor. visit_unit ( )
569
+ }
570
+
571
+ serde:: forward_to_deserialize_any! {
572
+ i8 i16 i32 i64
573
+ u8 u16 u32 u64
574
+ option
575
+ newtype_struct seq tuple tuple_struct map enum bool
576
+ f32 f64 char bytes
577
+ byte_buf unit unit_struct
578
+ identifier
579
+ }
580
+ }
581
+
487
582
/// A deserializer which takes two values and deserializes into a tuple of those
488
583
/// two values. This is similar to types like `StrDeserializer` in upstream
489
584
/// serde itself.
0 commit comments