toml/de/deserializer/
table.rs

1use serde::de::IntoDeserializer;
2use serde_spanned::Spanned;
3
4use crate::de::DeString;
5use crate::de::DeTable;
6use crate::de::DeValue;
7use crate::de::Error;
8use crate::map::IntoIter;
9
10pub(crate) struct TableDeserializer<'i> {
11    span: core::ops::Range<usize>,
12    items: DeTable<'i>,
13}
14
15impl<'i> TableDeserializer<'i> {
16    pub(crate) fn new(items: DeTable<'i>, span: core::ops::Range<usize>) -> Self {
17        Self { span, items }
18    }
19}
20
21impl<'de> serde::Deserializer<'de> for TableDeserializer<'de> {
22    type Error = Error;
23
24    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
25    where
26        V: serde::de::Visitor<'de>,
27    {
28        visitor.visit_map(TableMapAccess::new(self))
29    }
30
31    // `None` is interpreted as a missing field so be sure to implement `Some`
32    // as a present field.
33    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error>
34    where
35        V: serde::de::Visitor<'de>,
36    {
37        visitor.visit_some(self)
38    }
39
40    fn deserialize_newtype_struct<V>(
41        self,
42        _name: &'static str,
43        visitor: V,
44    ) -> Result<V::Value, Error>
45    where
46        V: serde::de::Visitor<'de>,
47    {
48        visitor.visit_newtype_struct(self)
49    }
50
51    fn deserialize_struct<V>(
52        self,
53        name: &'static str,
54        _fields: &'static [&'static str],
55        visitor: V,
56    ) -> Result<V::Value, Error>
57    where
58        V: serde::de::Visitor<'de>,
59    {
60        if serde_spanned::de::is_spanned(name) {
61            let span = self.span.clone();
62            return visitor.visit_map(super::SpannedDeserializer::new(self, span));
63        }
64
65        self.deserialize_any(visitor)
66    }
67
68    // Called when the type to deserialize is an enum, as opposed to a field in the type.
69    fn deserialize_enum<V>(
70        self,
71        _name: &'static str,
72        _variants: &'static [&'static str],
73        visitor: V,
74    ) -> Result<V::Value, Error>
75    where
76        V: serde::de::Visitor<'de>,
77    {
78        if self.items.is_empty() {
79            Err(Error::custom(
80                "wanted exactly 1 element, found 0 elements",
81                Some(self.span),
82            ))
83        } else if self.items.len() != 1 {
84            Err(Error::custom(
85                "wanted exactly 1 element, more than 1 element",
86                Some(self.span),
87            ))
88        } else {
89            visitor.visit_enum(TableMapAccess::new(self))
90        }
91    }
92
93    serde::forward_to_deserialize_any! {
94        bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq
95        bytes byte_buf map unit
96        ignored_any unit_struct tuple_struct tuple identifier
97    }
98}
99
100impl<'de> IntoDeserializer<'de, Error> for TableDeserializer<'de> {
101    type Deserializer = Self;
102
103    fn into_deserializer(self) -> Self::Deserializer {
104        self
105    }
106}
107
108pub(crate) struct TableMapAccess<'i> {
109    iter: IntoIter<Spanned<DeString<'i>>, Spanned<DeValue<'i>>>,
110    span: core::ops::Range<usize>,
111    value: Option<(Spanned<DeString<'i>>, Spanned<DeValue<'i>>)>,
112}
113
114impl<'i> TableMapAccess<'i> {
115    pub(crate) fn new(input: TableDeserializer<'i>) -> Self {
116        Self {
117            iter: input.items.into_iter(),
118            span: input.span,
119            value: None,
120        }
121    }
122}
123
124impl<'de> serde::de::MapAccess<'de> for TableMapAccess<'de> {
125    type Error = Error;
126
127    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
128    where
129        K: serde::de::DeserializeSeed<'de>,
130    {
131        match self.iter.next() {
132            Some((k, v)) => {
133                let key_span = k.span();
134                let ret = seed
135                    .deserialize(super::KeyDeserializer::new(
136                        k.clone().into_inner(),
137                        Some(key_span.clone()),
138                    ))
139                    .map(Some)
140                    .map_err(|mut e: Self::Error| {
141                        if e.span().is_none() {
142                            e.set_span(Some(key_span));
143                        }
144                        e
145                    });
146                self.value = Some((k, v));
147                ret
148            }
149            None => Ok(None),
150        }
151    }
152
153    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
154    where
155        V: serde::de::DeserializeSeed<'de>,
156    {
157        match self.value.take() {
158            Some((k, v)) => {
159                let span = v.span();
160                seed.deserialize(crate::de::ValueDeserializer::with_parts(
161                    v.into_inner(),
162                    span.clone(),
163                ))
164                .map_err(|mut e: Self::Error| {
165                    if e.span().is_none() {
166                        e.set_span(Some(span));
167                    }
168                    e.add_key(k.into_inner().into_owned());
169                    e
170                })
171            }
172            None => {
173                panic!("no more values in next_value_seed, internal error in ValueDeserializer")
174            }
175        }
176    }
177}
178
179impl<'de> serde::de::EnumAccess<'de> for TableMapAccess<'de> {
180    type Error = Error;
181    type Variant = super::TableEnumDeserializer<'de>;
182
183    fn variant_seed<V>(mut self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
184    where
185        V: serde::de::DeserializeSeed<'de>,
186    {
187        let (key, value) = match self.iter.next() {
188            Some(pair) => pair,
189            None => {
190                return Err(Error::custom(
191                    "expected table with exactly 1 entry, found empty table",
192                    Some(self.span),
193                ));
194            }
195        };
196
197        let key_span = key.span();
198        let val = seed
199            .deserialize(super::KeyDeserializer::new(
200                key.into_inner(),
201                Some(key_span.clone()),
202            ))
203            .map_err(|mut e: Self::Error| {
204                if e.span().is_none() {
205                    e.set_span(Some(key_span));
206                }
207                e
208            })?;
209
210        let value_span = value.span();
211        let value = value.into_inner();
212        let variant = super::TableEnumDeserializer::new(value, value_span);
213
214        Ok((val, variant))
215    }
216}