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::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}