1 use crate::de::Error;
2 
3 /// Deserializes table values into enum variants.
4 pub(crate) struct TableEnumDeserializer {
5     value: crate::Item,
6 }
7 
8 impl TableEnumDeserializer {
new(value: crate::Item) -> Self9     pub(crate) fn new(value: crate::Item) -> Self {
10         TableEnumDeserializer { value }
11     }
12 }
13 
14 impl<'de> serde::de::VariantAccess<'de> for TableEnumDeserializer {
15     type Error = Error;
16 
unit_variant(self) -> Result<(), Self::Error>17     fn unit_variant(self) -> Result<(), Self::Error> {
18         match self.value {
19             crate::Item::ArrayOfTables(values) => {
20                 if values.is_empty() {
21                     Ok(())
22                 } else {
23                     Err(Error::custom("expected empty array", values.span()))
24                 }
25             }
26             crate::Item::Value(crate::Value::Array(values)) => {
27                 if values.is_empty() {
28                     Ok(())
29                 } else {
30                     Err(Error::custom("expected empty table", values.span()))
31                 }
32             }
33             crate::Item::Table(values) => {
34                 if values.is_empty() {
35                     Ok(())
36                 } else {
37                     Err(Error::custom("expected empty table", values.span()))
38                 }
39             }
40             crate::Item::Value(crate::Value::InlineTable(values)) => {
41                 if values.is_empty() {
42                     Ok(())
43                 } else {
44                     Err(Error::custom("expected empty table", values.span()))
45                 }
46             }
47             e => Err(Error::custom(
48                 format!("expected table, found {}", e.type_name()),
49                 e.span(),
50             )),
51         }
52     }
53 
newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error> where T: serde::de::DeserializeSeed<'de>,54     fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
55     where
56         T: serde::de::DeserializeSeed<'de>,
57     {
58         seed.deserialize(super::ValueDeserializer::new(self.value))
59     }
60 
tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error> where V: serde::de::Visitor<'de>,61     fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
62     where
63         V: serde::de::Visitor<'de>,
64     {
65         match self.value {
66             crate::Item::ArrayOfTables(values) => {
67                 let values_span = values.span();
68                 let tuple_values = values.values.into_iter().collect::<Vec<_>>();
69 
70                 if tuple_values.len() == len {
71                     serde::de::Deserializer::deserialize_seq(
72                         super::ArrayDeserializer::new(tuple_values, values_span),
73                         visitor,
74                     )
75                 } else {
76                     Err(Error::custom(
77                         format!("expected tuple with length {}", len),
78                         values_span,
79                     ))
80                 }
81             }
82             crate::Item::Value(crate::Value::Array(values)) => {
83                 let values_span = values.span();
84                 let tuple_values = values.values.into_iter().collect::<Vec<_>>();
85 
86                 if tuple_values.len() == len {
87                     serde::de::Deserializer::deserialize_seq(
88                         super::ArrayDeserializer::new(tuple_values, values_span),
89                         visitor,
90                     )
91                 } else {
92                     Err(Error::custom(
93                         format!("expected tuple with length {}", len),
94                         values_span,
95                     ))
96                 }
97             }
98             crate::Item::Table(values) => {
99                 let values_span = values.span();
100                 let tuple_values: Result<Vec<_>, _> = values
101                     .items
102                     .into_iter()
103                     .enumerate()
104                     .map(
105                         |(index, (_, value))| match value.key.get().parse::<usize>() {
106                             Ok(key_index) if key_index == index => Ok(value.value),
107                             Ok(_) | Err(_) => Err(Error::custom(
108                                 format!(
109                                     "expected table key `{}`, but was `{}`",
110                                     index,
111                                     value.key.get()
112                                 ),
113                                 value.key.span(),
114                             )),
115                         },
116                     )
117                     .collect();
118                 let tuple_values = tuple_values?;
119 
120                 if tuple_values.len() == len {
121                     serde::de::Deserializer::deserialize_seq(
122                         super::ArrayDeserializer::new(tuple_values, values_span),
123                         visitor,
124                     )
125                 } else {
126                     Err(Error::custom(
127                         format!("expected tuple with length {}", len),
128                         values_span,
129                     ))
130                 }
131             }
132             crate::Item::Value(crate::Value::InlineTable(values)) => {
133                 let values_span = values.span();
134                 let tuple_values: Result<Vec<_>, _> = values
135                     .items
136                     .into_iter()
137                     .enumerate()
138                     .map(
139                         |(index, (_, value))| match value.key.get().parse::<usize>() {
140                             Ok(key_index) if key_index == index => Ok(value.value),
141                             Ok(_) | Err(_) => Err(Error::custom(
142                                 format!(
143                                     "expected table key `{}`, but was `{}`",
144                                     index,
145                                     value.key.get()
146                                 ),
147                                 value.key.span(),
148                             )),
149                         },
150                     )
151                     .collect();
152                 let tuple_values = tuple_values?;
153 
154                 if tuple_values.len() == len {
155                     serde::de::Deserializer::deserialize_seq(
156                         super::ArrayDeserializer::new(tuple_values, values_span),
157                         visitor,
158                     )
159                 } else {
160                     Err(Error::custom(
161                         format!("expected tuple with length {}", len),
162                         values_span,
163                     ))
164                 }
165             }
166             e => Err(Error::custom(
167                 format!("expected table, found {}", e.type_name()),
168                 e.span(),
169             )),
170         }
171     }
172 
struct_variant<V>( self, fields: &'static [&'static str], visitor: V, ) -> Result<V::Value, Self::Error> where V: serde::de::Visitor<'de>,173     fn struct_variant<V>(
174         self,
175         fields: &'static [&'static str],
176         visitor: V,
177     ) -> Result<V::Value, Self::Error>
178     where
179         V: serde::de::Visitor<'de>,
180     {
181         serde::de::Deserializer::deserialize_struct(
182             super::ValueDeserializer::new(self.value).with_struct_key_validation(),
183             "", // TODO: this should be the variant name
184             fields,
185             visitor,
186         )
187     }
188 }
189