@@ -184,7 +184,7 @@ pub trait Error: Sized {
184184 ProductKind :: Normal => "field" ,
185185 ProductKind :: ReducerArgs => "reducer argument" ,
186186 } ;
187- if let Some ( one_of) = one_of_names ( |n | expected. field_names ( n ) ) {
187+ if let Some ( one_of) = one_of_names ( || expected. field_names ( ) ) {
188188 Self :: custom ( format_args ! ( "unknown {el_ty} `{field_name}`, expected {one_of}" ) )
189189 } else {
190190 Self :: custom ( format_args ! ( "unknown {el_ty} `{field_name}`, there are no {el_ty}s" ) )
@@ -200,8 +200,8 @@ pub trait Error: Sized {
200200 }
201201
202202 /// The `name` is not that of a variant of the sum type.
203- fn unknown_variant_name < T : VariantVisitor > ( name : & str , expected : & T ) -> Self {
204- if let Some ( one_of) = one_of_names ( |n | expected. variant_names ( n ) ) {
203+ fn unknown_variant_name < ' de , T : VariantVisitor < ' de > > ( name : & str , expected : & T ) -> Self {
204+ if let Some ( one_of) = one_of_names ( || expected. variant_names ( ) . map ( Some ) ) {
205205 Self :: custom ( format_args ! ( "unknown variant `{name}`, expected {one_of}" , ) )
206206 } else {
207207 Self :: custom ( format_args ! ( "unknown variant `{name}`, there are no variants" ) )
@@ -358,39 +358,18 @@ pub trait FieldNameVisitor<'de> {
358358 ProductKind :: Normal
359359 }
360360
361- /// Provides the visitor the chance to add valid names into `names`.
362- fn field_names ( & self , names : & mut dyn ValidNames ) ;
361+ /// Provides a list of valid field names.
362+ ///
363+ /// Where `None` is yielded, this indicates a nameless field.
364+ fn field_names ( & self ) -> impl ' _ + Iterator < Item = Option < & str > > ;
363365
366+ /// Deserializes the name of a field using `name`.
364367 fn visit < E : Error > ( self , name : & str ) -> Result < Self :: Output , E > ;
365- }
366368
367- /// A trait for types storing a set of valid names.
368- pub trait ValidNames {
369- /// Adds the name `s` to the set.
370- fn push ( & mut self , s : & str ) ;
371-
372- /// Runs the function `names` provided with `self` as the store
373- /// and then returns back `self`.
374- /// This method exists for convenience.
375- fn run ( mut self , names : & impl Fn ( & mut dyn ValidNames ) ) -> Self
376- where
377- Self : Sized ,
378- {
379- names ( & mut self ) ;
380- self
381- }
382- }
383-
384- impl dyn ValidNames + ' _ {
385- /// Adds the names in `iter` to the set.
386- pub fn extend < I : IntoIterator > ( & mut self , iter : I )
387- where
388- I :: Item : AsRef < str > ,
389- {
390- for name in iter {
391- self . push ( name. as_ref ( ) )
392- }
393- }
369+ /// Deserializes the name of a field using `index`.
370+ ///
371+ /// The `name` is provided for error messages.
372+ fn visit_seq < E : Error > ( self , index : usize , name : & str ) -> Result < Self :: Output , E > ;
394373}
395374
396375/// A visitor walking through a [`Deserializer`] for sums.
@@ -442,17 +421,17 @@ pub trait SumAccess<'de> {
442421 /// The `visitor` is provided by the [`Deserializer`].
443422 /// This method is typically called from [`SumVisitor::visit_sum`]
444423 /// which will provide the [`V: VariantVisitor`](VariantVisitor).
445- fn variant < V : VariantVisitor > ( self , visitor : V ) -> Result < ( V :: Output , Self :: Variant ) , Self :: Error > ;
424+ fn variant < V : VariantVisitor < ' de > > ( self , visitor : V ) -> Result < ( V :: Output , Self :: Variant ) , Self :: Error > ;
446425}
447426
448427/// A visitor passed from [`SumVisitor`] to [`SumAccess::variant`]
449428/// which the latter uses to decide what variant to deserialize.
450- pub trait VariantVisitor {
429+ pub trait VariantVisitor < ' de > {
451430 /// The result of identifying a variant, e.g., some index type.
452431 type Output ;
453432
454- /// Provides the visitor the chance to add valid names into `names` .
455- fn variant_names ( & self , names : & mut dyn ValidNames ) ;
433+ /// Provides a list of variant names.
434+ fn variant_names ( & self ) -> impl ' _ + Iterator < Item = & str > ;
456435
457436 /// Identify the variant based on `tag`.
458437 fn visit_tag < E : Error > ( self , tag : u8 ) -> Result < Self :: Output , E > ;
@@ -669,71 +648,42 @@ impl<'de, T, const N: usize> ArrayVisitor<'de, T> for BasicArrayVisitor<N> {
669648 }
670649}
671650
672- /// Provided a function `names` that is allowed to store a name into a valid set ,
651+ /// Provided a list of names ,
673652/// returns a human readable list of all the names,
674653/// or `None` in the case of an empty list of names.
675- fn one_of_names ( names : impl Fn ( & mut dyn ValidNames ) ) -> Option < impl fmt:: Display > {
676- /// An implementation of `ValidNames` that just counts how many valid names are pushed into it.
677- struct CountNames ( usize ) ;
678-
679- impl ValidNames for CountNames {
680- fn push ( & mut self , _: & str ) {
681- self . 0 += 1
682- }
683- }
654+ fn one_of_names < ' a , I : Iterator < Item = Option < & ' a str > > > ( names : impl Fn ( ) -> I ) -> Option < impl fmt:: Display > {
655+ // Count how many names there are.
656+ let count = names ( ) . count ( ) ;
684657
685- /// An implementation of `ValidNames` that provides a human friendly enumeration of names.
686- struct OneOfNames < ' a , ' b > {
687- /// A `.push(_)` counter.
688- index : usize ,
689- /// How many names there were.
690- count : usize ,
691- /// Result of formatting thus far.
692- f : Result < & ' a mut fmt:: Formatter < ' b > , fmt:: Error > ,
693- }
694-
695- impl < ' a , ' b > OneOfNames < ' a , ' b > {
696- fn new ( count : usize , f : & ' a mut fmt:: Formatter < ' b > ) -> Self {
697- Self {
698- index : 0 ,
699- count,
700- f : Ok ( f) ,
701- }
702- }
703- }
704-
705- impl ValidNames for OneOfNames < ' _ , ' _ > {
706- fn push ( & mut self , name : & str ) {
707- // This will give us, after all `.push()`es have been made, the following:
658+ // There was at least one name; render those names.
659+ ( count != 0 ) . then ( move || {
660+ fmt_fn ( move |f| {
661+ let mut anon_name = 0 ;
662+ // An example of what happens for names "foo", "bar", and "baz":
708663 //
709664 // count = 1 -> "`foo`"
710665 // = 2 -> "`foo` or `bar`"
711666 // > 2 -> "one of `foo`, `bar`, or `baz`"
712-
713- let Ok ( f) = & mut self . f else {
714- return ;
715- } ;
716-
717- self . index += 1 ;
718-
719- if let Err ( e) = match ( self . count , self . index ) {
720- ( 1 , _) => write ! ( f, "`{name}`" ) ,
721- ( 2 , 1 ) => write ! ( f, "`{name}`" ) ,
722- ( 2 , 2 ) => write ! ( f, "`or `{name}`" ) ,
723- ( _, 1 ) => write ! ( f, "one of `{name}`" ) ,
724- ( c, i) if i < c => write ! ( f, ", `{name}`" ) ,
725- ( _, _) => write ! ( f, ", `, or {name}`" ) ,
726- } {
727- self . f = Err ( e) ;
667+ for ( index, mut name) in names ( ) . enumerate ( ) {
668+ let mut name_buf: String = String :: new ( ) ;
669+ let name = name. get_or_insert_with ( || {
670+ name_buf = format ! ( "{anon_name}" ) ;
671+ anon_name += 1 ;
672+ & name_buf
673+ } ) ;
674+ match ( count, index) {
675+ ( 1 , _) => write ! ( f, "`{name}`" ) ,
676+ ( 2 , 1 ) => write ! ( f, "`{name}`" ) ,
677+ ( 2 , 2 ) => write ! ( f, "`or `{name}`" ) ,
678+ ( _, 1 ) => write ! ( f, "one of `{name}`" ) ,
679+ ( c, i) if i < c => write ! ( f, ", `{name}`" ) ,
680+ ( _, _) => write ! ( f, ", `, or {name}`" ) ,
681+ } ?;
728682 }
729- }
730- }
731683
732- // Count how many names have been pushed.
733- let count = CountNames ( 0 ) . run ( & names) . 0 ;
734-
735- // There was at least one name; render those names.
736- ( count != 0 ) . then ( || fmt_fn ( move |fmt| OneOfNames :: new ( count, fmt) . run ( & names) . f . map ( drop) ) )
684+ Ok ( ( ) )
685+ } )
686+ } )
737687}
738688
739689/// Deserializes `none` variant of an optional value.
@@ -752,11 +702,11 @@ impl<E: Error> Default for NoneAccess<E> {
752702 }
753703}
754704
755- impl < E : Error > SumAccess < ' _ > for NoneAccess < E > {
705+ impl < ' de , E : Error > SumAccess < ' de > for NoneAccess < E > {
756706 type Error = E ;
757707 type Variant = Self ;
758708
759- fn variant < V : VariantVisitor > ( self , visitor : V ) -> Result < ( V :: Output , Self :: Variant ) , Self :: Error > {
709+ fn variant < V : VariantVisitor < ' de > > ( self , visitor : V ) -> Result < ( V :: Output , Self :: Variant ) , Self :: Error > {
760710 visitor. visit_name ( "none" ) . map ( |var| ( var, self ) )
761711 }
762712}
0 commit comments