toml_edit/de/
table_enum.rs

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(|(index, (key, value))| match key.get().parse::<usize>() {
105                        Ok(key_index) if key_index == index => Ok(value),
106                        Ok(_) | Err(_) => Err(Error::custom(
107                            format!("expected table key `{}`, but was `{}`", index, key.get()),
108                            key.span(),
109                        )),
110                    })
111                    .collect();
112                let tuple_values = tuple_values?;
113
114                if tuple_values.len() == len {
115                    serde::de::Deserializer::deserialize_seq(
116                        super::ArrayDeserializer::new(tuple_values, values_span),
117                        visitor,
118                    )
119                } else {
120                    Err(Error::custom(
121                        format!("expected tuple with length {}", len),
122                        values_span,
123                    ))
124                }
125            }
126            crate::Item::Value(crate::Value::InlineTable(values)) => {
127                let values_span = values.span();
128                let tuple_values: Result<Vec<_>, _> = values
129                    .items
130                    .into_iter()
131                    .enumerate()
132                    .map(|(index, (key, value))| match key.get().parse::<usize>() {
133                        Ok(key_index) if key_index == index => Ok(value),
134                        Ok(_) | Err(_) => Err(Error::custom(
135                            format!("expected table key `{}`, but was `{}`", index, key.get()),
136                            key.span(),
137                        )),
138                    })
139                    .collect();
140                let tuple_values = tuple_values?;
141
142                if tuple_values.len() == len {
143                    serde::de::Deserializer::deserialize_seq(
144                        super::ArrayDeserializer::new(tuple_values, values_span),
145                        visitor,
146                    )
147                } else {
148                    Err(Error::custom(
149                        format!("expected tuple with length {}", len),
150                        values_span,
151                    ))
152                }
153            }
154            e => Err(Error::custom(
155                format!("expected table, found {}", e.type_name()),
156                e.span(),
157            )),
158        }
159    }
160
161    fn struct_variant<V>(
162        self,
163        fields: &'static [&'static str],
164        visitor: V,
165    ) -> Result<V::Value, Self::Error>
166    where
167        V: serde::de::Visitor<'de>,
168    {
169        serde::de::Deserializer::deserialize_struct(
170            super::ValueDeserializer::new(self.value).with_struct_key_validation(),
171            "", // TODO: this should be the variant name
172            fields,
173            visitor,
174        )
175    }
176}