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::Table(values) => {
20 if values.is_empty() {
21 Ok(())
22 } else {
23 Err(Error::custom("expected empty table", values.span()))
24 }
25 }
26 crate::Item::Value(crate::Value::InlineTable(values)) => {
27 if values.is_empty() {
28 Ok(())
29 } else {
30 Err(Error::custom("expected empty table", values.span()))
31 }
32 }
33 e => Err(Error::custom(
34 format!("expected table, found {}", e.type_name()),
35 e.span(),
36 )),
37 }
38 }
39
40 fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
41 where
42 T: serde::de::DeserializeSeed<'de>,
43 {
44 seed.deserialize(super::ValueDeserializer::new(self.value))
45 }
46
47 fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
48 where
49 V: serde::de::Visitor<'de>,
50 {
51 match self.value {
52 crate::Item::Table(values) => {
53 let values_span = values.span();
54 let tuple_values = values
55 .items
56 .into_iter()
57 .enumerate()
58 .map(
59 |(index, (_, value))| match value.key.get().parse::<usize>() {
60 Ok(key_index) if key_index == index => Ok(value.value),
61 Ok(_) | Err(_) => Err(Error::custom(
62 format!(
63 "expected table key `{}`, but was `{}`",
64 index,
65 value.key.get()
66 ),
67 value.key.span(),
68 )),
69 },
70 )
71 // Fold all values into a `Vec`, or return the first error.
72 .fold(Ok(Vec::with_capacity(len)), |result, value_result| {
73 result.and_then(move |mut tuple_values| match value_result {
74 Ok(value) => {
75 tuple_values.push(value);
76 Ok(tuple_values)
77 }
78 // `Result<de::Value, Self::Error>` to `Result<Vec<_>, Self::Error>`
79 Err(e) => Err(e),
80 })
81 })?;
82
83 if tuple_values.len() == len {
84 serde::de::Deserializer::deserialize_seq(
85 super::ArrayDeserializer::new(tuple_values, values_span),
86 visitor,
87 )
88 } else {
89 Err(Error::custom(
90 format!("expected tuple with length {}", len),
91 values_span,
92 ))
93 }
94 }
95 crate::Item::Value(crate::Value::InlineTable(values)) => {
96 let values_span = values.span();
97 let tuple_values = values
98 .items
99 .into_iter()
100 .enumerate()
101 .map(
102 |(index, (_, value))| match value.key.get().parse::<usize>() {
103 Ok(key_index) if key_index == index => Ok(value.value),
104 Ok(_) | Err(_) => Err(Error::custom(
105 format!(
106 "expected table key `{}`, but was `{}`",
107 index,
108 value.key.get()
109 ),
110 value.key.span(),
111 )),
112 },
113 )
114 // Fold all values into a `Vec`, or return the first error.
115 .fold(Ok(Vec::with_capacity(len)), |result, value_result| {
116 result.and_then(move |mut tuple_values| match value_result {
117 Ok(value) => {
118 tuple_values.push(value);
119 Ok(tuple_values)
120 }
121 // `Result<de::Value, Self::Error>` to `Result<Vec<_>, Self::Error>`
122 Err(e) => Err(e),
123 })
124 })?;
125
126 if tuple_values.len() == len {
127 serde::de::Deserializer::deserialize_seq(
128 super::ArrayDeserializer::new(tuple_values, values_span),
129 visitor,
130 )
131 } else {
132 Err(Error::custom(
133 format!("expected tuple with length {}", len),
134 values_span,
135 ))
136 }
137 }
138 e => Err(Error::custom(
139 format!("expected table, found {}", e.type_name()),
140 e.span(),
141 )),
142 }
143 }
144
145 fn struct_variant<V>(
146 self,
147 fields: &'static [&'static str],
148 visitor: V,
149 ) -> Result<V::Value, Self::Error>
150 where
151 V: serde::de::Visitor<'de>,
152 {
153 serde::de::Deserializer::deserialize_struct(
154 super::ValueDeserializer::new(self.value).with_struct_key_validation(),
155 "", // TODO: this should be the variant name
156 fields,
157 visitor,
158 )
159 }
160}
161