1use crate::de::Error;
2
3/// Deserializes table values into enum variants.
4pub(crate) struct TableEnumDeserializer {
5 value: crate::Item,
6}
7
8impl TableEnumDeserializer {
9 pub(crate) fn new(value: crate::Item) -> Self {
10 TableEnumDeserializer { value }
11 }
12}
13
14impl<'de> serde::de::VariantAccess<'de> for TableEnumDeserializer {
15 type Error = Error;
16
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
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
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
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