@@ -12,7 +12,8 @@ use serde::de::{
12
12
use serde:: Deserialize ;
13
13
use std:: any:: TypeId ;
14
14
use std:: fmt;
15
- use std:: fmt:: Formatter ;
15
+ use std:: fmt:: { Debug , Display , Formatter } ;
16
+ use std:: slice:: Iter ;
16
17
17
18
pub trait DeserializeValue {
18
19
fn deserialize (
@@ -24,7 +25,7 @@ pub trait DeserializeValue {
24
25
trait StructLikeInfo {
25
26
fn get_name ( & self ) -> & str ;
26
27
fn get_field ( & self , name : & str ) -> Option < & NamedField > ;
27
- fn get_field_names ( & self ) -> & [ & ' static str ] ;
28
+ fn iter_fields ( & self ) -> Iter < ' _ , NamedField > ;
28
29
}
29
30
30
31
trait TupleLikeInfo {
@@ -42,8 +43,8 @@ impl StructLikeInfo for StructInfo {
42
43
self . field ( name)
43
44
}
44
45
45
- fn get_field_names ( & self ) -> & [ & ' static str ] {
46
- self . field_names ( )
46
+ fn iter_fields ( & self ) -> Iter < ' _ , NamedField > {
47
+ self . iter ( )
47
48
}
48
49
}
49
50
@@ -56,8 +57,8 @@ impl StructLikeInfo for StructVariantInfo {
56
57
self . field ( name)
57
58
}
58
59
59
- fn get_field_names ( & self ) -> & [ & ' static str ] {
60
- self . field_names ( )
60
+ fn iter_fields ( & self ) -> Iter < ' _ , NamedField > {
61
+ self . iter ( )
61
62
}
62
63
}
63
64
@@ -89,6 +90,39 @@ impl TupleLikeInfo for TupleVariantInfo {
89
90
}
90
91
}
91
92
93
+ /// A debug struct used for error messages that displays a list of expected values.
94
+ ///
95
+ /// # Example
96
+ ///
97
+ /// ```ignore
98
+ /// let expected = vec!["foo", "bar", "baz"];
99
+ /// assert_eq!("`foo`, `bar`, `baz`", format!("{}", ExpectedValues(expected)));
100
+ /// ```
101
+ struct ExpectedValues < TIntoIter , TIter , TItem > ( TIntoIter )
102
+ where
103
+ TIntoIter : IntoIterator < IntoIter = TIter > + Clone ,
104
+ TIter : Iterator < Item = TItem > + ExactSizeIterator ,
105
+ TItem : Display ;
106
+
107
+ impl < TIntoIter , TIter , TItem > Debug for ExpectedValues < TIntoIter , TIter , TItem >
108
+ where
109
+ TIntoIter : IntoIterator < IntoIter = TIter > + Clone ,
110
+ TIter : Iterator < Item = TItem > + ExactSizeIterator ,
111
+ TItem : Display ,
112
+ {
113
+ fn fmt ( & self , f : & mut Formatter < ' _ > ) -> fmt:: Result {
114
+ let iter = self . 0 . clone ( ) . into_iter ( ) ;
115
+ let len = iter. len ( ) ;
116
+ for ( index, item) in iter. enumerate ( ) {
117
+ write ! ( f, "`{}`" , item) ?;
118
+ if index < len - 1 {
119
+ write ! ( f, ", " ) ?;
120
+ }
121
+ }
122
+ Ok ( ( ) )
123
+ }
124
+ }
125
+
92
126
/// Represents a simple reflected identifier.
93
127
#[ derive( Debug , Clone , Eq , PartialEq ) ]
94
128
struct Ident ( String ) ;
@@ -254,7 +288,8 @@ impl<'a, 'de> DeserializeSeed<'de> for TypedReflectDeserializer<'a> {
254
288
TypeInfo :: Struct ( struct_info) => {
255
289
let mut dynamic_struct = deserializer. deserialize_struct (
256
290
struct_info. name ( ) ,
257
- struct_info. field_names ( ) ,
291
+ // Field names are mainly just a hint, we don't necessarily need to store and pass that data
292
+ & [ ] ,
258
293
StructVisitor {
259
294
struct_info,
260
295
registry : self . registry ,
@@ -323,7 +358,8 @@ impl<'a, 'de> DeserializeSeed<'de> for TypedReflectDeserializer<'a> {
323
358
} else {
324
359
deserializer. deserialize_enum (
325
360
enum_info. name ( ) ,
326
- enum_info. variant_names ( ) ,
361
+ // Variant names are mainly just a hint, we don't necessarily need to store and pass that data
362
+ & [ ] ,
327
363
EnumVisitor {
328
364
enum_info,
329
365
registry : self . registry ,
@@ -576,15 +612,20 @@ impl<'a, 'de> Visitor<'de> for EnumVisitor<'a> {
576
612
{
577
613
let mut dynamic_enum = DynamicEnum :: default ( ) ;
578
614
let ( Ident ( variant_name) , variant) = data. variant ( ) . unwrap ( ) ;
579
- let variant_info = self
580
- . enum_info
581
- . variant ( & variant_name)
582
- . ok_or_else ( || Error :: unknown_variant ( & variant_name, self . enum_info . variant_names ( ) ) ) ?;
615
+ let variant_info = self . enum_info . variant ( & variant_name) . ok_or_else ( || {
616
+ let names = self . enum_info . iter ( ) . map ( |variant| variant. name ( ) ) ;
617
+ Error :: custom ( format_args ! (
618
+ "unknown variant `{}`, expected one of {:?}" ,
619
+ variant_name,
620
+ ExpectedValues ( names)
621
+ ) )
622
+ } ) ?;
583
623
let value: DynamicVariant = match variant_info {
584
624
VariantInfo :: Unit ( ..) => variant. unit_variant ( ) ?. into ( ) ,
585
625
VariantInfo :: Struct ( struct_info) => variant
586
626
. struct_variant (
587
- struct_info. field_names ( ) ,
627
+ // Field names are mainly just a hint, we don't necessarily need to store and pass that data
628
+ & [ ] ,
588
629
StructVariantVisitor {
589
630
struct_info,
590
631
registry : self . registry ,
@@ -720,9 +761,14 @@ where
720
761
{
721
762
let mut dynamic_struct = DynamicStruct :: default ( ) ;
722
763
while let Some ( Ident ( key) ) = map. next_key :: < Ident > ( ) ? {
723
- let field = info
724
- . get_field ( & key)
725
- . ok_or_else ( || Error :: unknown_field ( & key, info. get_field_names ( ) ) ) ?;
764
+ let field = info. get_field ( & key) . ok_or_else ( || {
765
+ let fields = info. iter_fields ( ) . map ( |field| field. name ( ) ) ;
766
+ Error :: custom ( format_args ! (
767
+ "unknown field `{}`, expected one of {:?}" ,
768
+ key,
769
+ ExpectedValues ( fields)
770
+ ) )
771
+ } ) ?;
726
772
let registration = get_registration ( field. type_id ( ) , field. type_name ( ) , registry) ?;
727
773
let value = map. next_value_seed ( TypedReflectDeserializer {
728
774
registration,
0 commit comments