toml/de/deserializer/
table_enum.rs

1use crate::alloc_prelude::*;
2use crate::de::DeArray;
3use crate::de::DeValue;
4use crate::de::Error;
5
6/// Deserializes table values into enum variants.
7pub(crate) struct TableEnumDeserializer<'i> {
8    value: DeValue<'i>,
9    span: core::ops::Range<usize>,
10}
11
12impl<'i> TableEnumDeserializer<'i> {
13    pub(crate) fn new(value: DeValue<'i>, span: core::ops::Range<usize>) -> Self {
14        TableEnumDeserializer { value, span }
15    }
16}
17
18impl<'de> serde::de::VariantAccess<'de> for TableEnumDeserializer<'de> {
19    type Error = Error;
20
21    fn unit_variant(self) -> Result<(), Self::Error> {
22        match self.value {
23            DeValue::Array(values) => {
24                if values.is_empty() {
25                    Ok(())
26                } else {
27                    Err(Error::custom("expected empty array", Some(self.span)))
28                }
29            }
30            DeValue::Table(values) => {
31                if values.is_empty() {
32                    Ok(())
33                } else {
34                    Err(Error::custom("expected empty table", Some(self.span)))
35                }
36            }
37            e => Err(Error::custom(
38                format!("expected table, found {}", e.type_str()),
39                Some(self.span),
40            )),
41        }
42    }
43
44    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
45    where
46        T: serde::de::DeserializeSeed<'de>,
47    {
48        seed.deserialize(super::ValueDeserializer::with_parts(self.value, self.span))
49    }
50
51    fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
52    where
53        V: serde::de::Visitor<'de>,
54    {
55        match self.value {
56            DeValue::Array(values) => {
57                let values_span = self.span.clone();
58                let tuple_values = values;
59
60                if tuple_values.len() == len {
61                    serde::de::Deserializer::deserialize_seq(
62                        super::ArrayDeserializer::new(tuple_values, values_span),
63                        visitor,
64                    )
65                } else {
66                    Err(Error::custom(
67                        format!("expected tuple with length {len}"),
68                        Some(values_span),
69                    ))
70                }
71            }
72            DeValue::Table(values) => {
73                let values_span = self.span.clone();
74                let tuple_values: Result<DeArray<'_>, _> = values
75                    .into_iter()
76                    .enumerate()
77                    .map(
78                        |(index, (key, value))| match key.get_ref().parse::<usize>() {
79                            Ok(key_index) if key_index == index => Ok(value),
80                            Ok(_) | Err(_) => Err(Error::custom(
81                                format!("expected table key `{index}`, but was `{key}`"),
82                                Some(key.span()),
83                            )),
84                        },
85                    )
86                    .collect();
87                let tuple_values = tuple_values?;
88
89                if tuple_values.len() == len {
90                    serde::de::Deserializer::deserialize_seq(
91                        super::ArrayDeserializer::new(tuple_values, values_span),
92                        visitor,
93                    )
94                } else {
95                    Err(Error::custom(
96                        format!("expected tuple with length {len}"),
97                        Some(values_span),
98                    ))
99                }
100            }
101            e => Err(Error::custom(
102                format!("expected table, found {}", e.type_str()),
103                Some(self.span),
104            )),
105        }
106    }
107
108    fn struct_variant<V>(
109        self,
110        fields: &'static [&'static str],
111        visitor: V,
112    ) -> Result<V::Value, Self::Error>
113    where
114        V: serde::de::Visitor<'de>,
115    {
116        serde::de::Deserializer::deserialize_struct(
117            super::ValueDeserializer::with_parts(self.value, self.span)
118                .with_struct_key_validation(),
119            "", // TODO: this should be the variant name
120            fields,
121            visitor,
122        )
123    }
124}