@@ -384,7 +384,12 @@ impl<'de> de::SeqAccess<'de> for ConfigSeqAccess {
384384 {
385385 match self . list_iter . next ( ) {
386386 // 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+ }
388393 None => Ok ( None ) ,
389394 }
390395 }
@@ -400,7 +405,17 @@ impl<'de> de::SeqAccess<'de> for ConfigSeqAccess {
400405struct ValueDeserializer < ' config > {
401406 hits : u32 ,
402407 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 > ,
404419}
405420
406421impl < ' config > ValueDeserializer < ' config > {
@@ -428,9 +443,19 @@ impl<'config> ValueDeserializer<'config> {
428443 Ok ( ValueDeserializer {
429444 hits : 0 ,
430445 definition,
431- de,
446+ de : Some ( de) ,
447+ str_value : None ,
432448 } )
433449 }
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+ }
434459}
435460
436461impl < ' de , ' config > de:: MapAccess < ' de > for ValueDeserializer < ' config > {
@@ -459,9 +484,14 @@ impl<'de, 'config> de::MapAccess<'de> for ValueDeserializer<'config> {
459484 // If this is the first time around we deserialize the `value` field
460485 // which is the actual deserializer
461486 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+ }
465495 }
466496
467497 // ... otherwise we're deserializing the `definition` field, so we need
@@ -484,6 +514,71 @@ impl<'de, 'config> de::MapAccess<'de> for ValueDeserializer<'config> {
484514 }
485515}
486516
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+
487582/// A deserializer which takes two values and deserializes into a tuple of those
488583/// two values. This is similar to types like `StrDeserializer` in upstream
489584/// serde itself.
0 commit comments