Skip to main content

toml_edit/de/
table.rs

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