toml/de/deserializer/
value.rs

1use serde::de::IntoDeserializer as _;
2use serde_spanned::Spanned;
3
4use super::ArrayDeserializer;
5use super::DatetimeDeserializer;
6use super::TableDeserializer;
7use crate::alloc_prelude::*;
8use crate::de::DeString;
9use crate::de::DeTable;
10use crate::de::DeValue;
11use crate::de::Error;
12
13/// Deserialization implementation for TOML [values][crate::Value].
14///
15/// # Example
16///
17/// ```
18/// # #[cfg(feature = "parse")] {
19/// # #[cfg(feature = "display")] {
20/// use serde::Deserialize;
21///
22/// #[derive(Deserialize)]
23/// struct Config {
24///     title: String,
25///     owner: Owner,
26/// }
27///
28/// #[derive(Deserialize)]
29/// struct Owner {
30///     name: String,
31/// }
32///
33/// let value = r#"{ title = 'TOML Example', owner = { name = 'Lisa' } }"#;
34/// let deserializer = toml::de::ValueDeserializer::parse(value).unwrap();
35/// let config = Config::deserialize(deserializer).unwrap();
36/// assert_eq!(config.title, "TOML Example");
37/// assert_eq!(config.owner.name, "Lisa");
38/// # }
39/// # }
40/// ```
41pub struct ValueDeserializer<'i> {
42    span: core::ops::Range<usize>,
43    input: DeValue<'i>,
44    validate_struct_keys: bool,
45}
46
47impl<'i> ValueDeserializer<'i> {
48    /// Parse a TOML value
49    pub fn parse(raw: &'i str) -> Result<Self, Error> {
50        let input = DeValue::parse(raw)?;
51        let span = input.span();
52        let input = input.into_inner();
53        Ok(Self::with_parts(input, span))
54    }
55
56    /// Deprecated, replaced with [`ValueDeserializer::parse`]
57    #[deprecated(since = "0.9.0", note = "replaced with `ValueDeserializer::parse`")]
58    pub fn new(raw: &'i str) -> Result<Self, Error> {
59        Self::parse(raw)
60    }
61
62    pub(crate) fn with_parts(input: DeValue<'i>, span: core::ops::Range<usize>) -> Self {
63        Self {
64            input,
65            span,
66            validate_struct_keys: false,
67        }
68    }
69
70    pub(crate) fn with_struct_key_validation(mut self) -> Self {
71        self.validate_struct_keys = true;
72        self
73    }
74}
75
76impl<'i> From<Spanned<DeValue<'i>>> for ValueDeserializer<'i> {
77    fn from(root: Spanned<DeValue<'i>>) -> Self {
78        let span = root.span();
79        let root = root.into_inner();
80        Self::with_parts(root, span)
81    }
82}
83
84impl<'de> serde::Deserializer<'de> for ValueDeserializer<'de> {
85    type Error = Error;
86
87    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
88    where
89        V: serde::de::Visitor<'de>,
90    {
91        let span = self.span.clone();
92        match self.input {
93            DeValue::String(DeString::Owned(v)) => visitor.visit_string(v),
94            DeValue::String(DeString::Borrowed(v)) => visitor.visit_str(v),
95            DeValue::Integer(v) => {
96                if let Some(v) = v.to_i64() {
97                    visitor.visit_i64(v)
98                } else if let Some(v) = v.to_u64() {
99                    visitor.visit_u64(v)
100                } else if let Some(v) = v.to_i128() {
101                    visitor.visit_i128(v)
102                } else if let Some(v) = v.to_u128() {
103                    visitor.visit_u128(v)
104                } else {
105                    Err(Error::custom("integer number overflowed", None))
106                }
107            }
108            DeValue::Float(v) => {
109                if let Some(v) = v.to_f64() {
110                    visitor.visit_f64(v)
111                } else {
112                    Err(Error::custom("floating-point number overflowed", None))
113                }
114            }
115            DeValue::Boolean(v) => visitor.visit_bool(v),
116            DeValue::Datetime(v) => visitor.visit_map(DatetimeDeserializer::new(v)),
117            DeValue::Array(v) => ArrayDeserializer::new(v, span.clone()).deserialize_any(visitor),
118            DeValue::Table(v) => TableDeserializer::new(v, span.clone()).deserialize_any(visitor),
119        }
120        .map_err(|mut e: Self::Error| {
121            if e.span().is_none() {
122                e.set_span(Some(span));
123            }
124            e
125        })
126    }
127
128    fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value, Error>
129    where
130        V: serde::de::Visitor<'de>,
131    {
132        self.deserialize_any(visitor)
133    }
134
135    fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value, Error>
136    where
137        V: serde::de::Visitor<'de>,
138    {
139        self.deserialize_any(visitor)
140    }
141
142    // `None` is interpreted as a missing field so be sure to implement `Some`
143    // as a present field.
144    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error>
145    where
146        V: serde::de::Visitor<'de>,
147    {
148        let span = self.span.clone();
149        visitor.visit_some(self).map_err(|mut e: Self::Error| {
150            if e.span().is_none() {
151                e.set_span(Some(span));
152            }
153            e
154        })
155    }
156
157    fn deserialize_newtype_struct<V>(
158        self,
159        _name: &'static str,
160        visitor: V,
161    ) -> Result<V::Value, Error>
162    where
163        V: serde::de::Visitor<'de>,
164    {
165        let span = self.span.clone();
166        visitor
167            .visit_newtype_struct(self)
168            .map_err(|mut e: Self::Error| {
169                if e.span().is_none() {
170                    e.set_span(Some(span));
171                }
172                e
173            })
174    }
175
176    fn deserialize_struct<V>(
177        self,
178        name: &'static str,
179        fields: &'static [&'static str],
180        visitor: V,
181    ) -> Result<V::Value, Error>
182    where
183        V: serde::de::Visitor<'de>,
184    {
185        if serde_spanned::de::is_spanned(name) {
186            let span = self.span.clone();
187            return visitor.visit_map(super::SpannedDeserializer::new(self, span));
188        }
189
190        if toml_datetime::de::is_datetime(name) {
191            let span = self.span.clone();
192            if let DeValue::Datetime(d) = self.input {
193                return visitor.visit_map(DatetimeDeserializer::new(d)).map_err(
194                    |mut e: Self::Error| {
195                        if e.span().is_none() {
196                            e.set_span(Some(span));
197                        }
198                        e
199                    },
200                );
201            }
202        }
203
204        if self.validate_struct_keys {
205            let span = self.span.clone();
206            match &self.input {
207                DeValue::Table(values) => validate_struct_keys(values, fields),
208                _ => Ok(()),
209            }
210            .map_err(|mut e: Self::Error| {
211                if e.span().is_none() {
212                    e.set_span(Some(span));
213                }
214                e
215            })?;
216        }
217
218        self.deserialize_any(visitor)
219    }
220
221    // Called when the type to deserialize is an enum, as opposed to a field in the type.
222    fn deserialize_enum<V>(
223        self,
224        name: &'static str,
225        variants: &'static [&'static str],
226        visitor: V,
227    ) -> Result<V::Value, Error>
228    where
229        V: serde::de::Visitor<'de>,
230    {
231        let span = self.span.clone();
232        match self.input {
233            DeValue::String(v) => visitor.visit_enum(v.into_deserializer()),
234            DeValue::Table(v) => {
235                TableDeserializer::new(v, span.clone()).deserialize_enum(name, variants, visitor)
236            }
237            _ => Err(Error::custom("wanted string or table", Some(span.clone()))),
238        }
239        .map_err(|mut e: Self::Error| {
240            if e.span().is_none() {
241                e.set_span(Some(span));
242            }
243            e
244        })
245    }
246
247    serde::forward_to_deserialize_any! {
248        bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq
249        bytes byte_buf map unit
250        ignored_any unit_struct tuple_struct tuple identifier
251    }
252}
253
254impl<'de> serde::de::IntoDeserializer<'de, Error> for ValueDeserializer<'de> {
255    type Deserializer = Self;
256
257    fn into_deserializer(self) -> Self::Deserializer {
258        self
259    }
260}
261
262impl<'de> serde::de::IntoDeserializer<'de, Error> for Spanned<DeValue<'de>> {
263    type Deserializer = ValueDeserializer<'de>;
264
265    fn into_deserializer(self) -> Self::Deserializer {
266        ValueDeserializer::from(self)
267    }
268}
269
270pub(crate) fn validate_struct_keys(
271    table: &DeTable<'_>,
272    fields: &'static [&'static str],
273) -> Result<(), Error> {
274    let extra_fields = table
275        .keys()
276        .filter_map(|key| {
277            if !fields.contains(&key.get_ref().as_ref()) {
278                Some(key.clone())
279            } else {
280                None
281            }
282        })
283        .collect::<Vec<_>>();
284
285    if extra_fields.is_empty() {
286        Ok(())
287    } else {
288        Err(Error::custom(
289            format!(
290                "unexpected keys in table: {}, available keys: {}",
291                extra_fields
292                    .iter()
293                    .map(|k| k.get_ref().as_ref())
294                    .collect::<Vec<_>>()
295                    .join(", "),
296                fields.join(", "),
297            ),
298            Some(extra_fields[0].span()),
299        ))
300    }
301}