toml_edit/de/
mod.rs

1//! Deserializing TOML into Rust structures.
2//!
3//! This module contains all the Serde support for deserializing TOML documents into Rust structures.
4
5use serde::de::DeserializeOwned;
6
7mod array;
8mod datetime;
9mod key;
10mod spanned;
11mod table;
12mod table_enum;
13mod value;
14
15use array::ArrayDeserializer;
16use datetime::DatetimeDeserializer;
17use key::KeyDeserializer;
18use spanned::SpannedDeserializer;
19use table::TableMapAccess;
20use table_enum::TableEnumDeserializer;
21
22pub use value::ValueDeserializer;
23
24/// Errors that can occur when deserializing a type.
25#[derive(Debug, Clone, PartialEq, Eq)]
26pub struct Error {
27    inner: crate::TomlError,
28}
29
30impl Error {
31    pub(crate) fn custom<T>(msg: T, span: Option<std::ops::Range<usize>>) -> Self
32    where
33        T: std::fmt::Display,
34    {
35        Error {
36            inner: crate::TomlError::custom(msg.to_string(), span),
37        }
38    }
39
40    /// Add key while unwinding
41    pub fn add_key(&mut self, key: String) {
42        self.inner.add_key(key)
43    }
44
45    /// What went wrong
46    pub fn message(&self) -> &str {
47        self.inner.message()
48    }
49
50    /// The start/end index into the original document where the error occurred
51    pub fn span(&self) -> Option<std::ops::Range<usize>> {
52        self.inner.span()
53    }
54
55    pub(crate) fn set_span(&mut self, span: Option<std::ops::Range<usize>>) {
56        self.inner.set_span(span);
57    }
58
59    /// Produces a (line, column) pair of the position of the error if available
60    ///
61    /// All indexes are 0-based.
62    #[deprecated(since = "0.18.0", note = "See instead `Error::span`")]
63    pub fn line_col(&self) -> Option<(usize, usize)> {
64        #[allow(deprecated)]
65        self.inner.line_col()
66    }
67}
68
69impl serde::de::Error for Error {
70    fn custom<T>(msg: T) -> Self
71    where
72        T: std::fmt::Display,
73    {
74        Error::custom(msg, None)
75    }
76}
77
78impl std::fmt::Display for Error {
79    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
80        self.inner.fmt(f)
81    }
82}
83
84impl From<crate::TomlError> for Error {
85    fn from(e: crate::TomlError) -> Error {
86        Self { inner: e }
87    }
88}
89
90impl From<Error> for crate::TomlError {
91    fn from(e: Error) -> crate::TomlError {
92        e.inner
93    }
94}
95
96impl std::error::Error for Error {}
97
98/// Convert a value into `T`.
99pub fn from_str<T>(s: &'_ str) -> Result<T, Error>
100where
101    T: DeserializeOwned,
102{
103    let de = s.parse::<Deserializer>()?;
104    T::deserialize(de)
105}
106
107/// Convert a value into `T`.
108pub fn from_slice<T>(s: &'_ [u8]) -> Result<T, Error>
109where
110    T: DeserializeOwned,
111{
112    let s = std::str::from_utf8(s).map_err(|e| Error::custom(e, None))?;
113    from_str(s)
114}
115
116/// Convert a document into `T`.
117pub fn from_document<T>(d: crate::Document) -> Result<T, Error>
118where
119    T: DeserializeOwned,
120{
121    let deserializer = Deserializer::new(d);
122    T::deserialize(deserializer)
123}
124
125/// Deserialization for TOML [documents][crate::Document].
126pub struct Deserializer {
127    input: crate::Document,
128}
129
130impl Deserializer {
131    /// Deserialization implementation for TOML.
132    pub fn new(input: crate::Document) -> Self {
133        Self { input }
134    }
135}
136
137impl std::str::FromStr for Deserializer {
138    type Err = Error;
139
140    /// Parses a document from a &str
141    fn from_str(s: &str) -> Result<Self, Self::Err> {
142        let d = crate::parser::parse_document(s).map_err(Error::from)?;
143        Ok(Self::new(d))
144    }
145}
146
147// Note: this is wrapped by `toml::de::Deserializer` and any trait methods
148// implemented here need to be wrapped there
149impl<'de> serde::Deserializer<'de> for Deserializer {
150    type Error = Error;
151
152    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
153    where
154        V: serde::de::Visitor<'de>,
155    {
156        let original = self.input.original;
157        self.input
158            .root
159            .into_deserializer()
160            .deserialize_any(visitor)
161            .map_err(|mut e: Self::Error| {
162                e.inner.set_original(original);
163                e
164            })
165    }
166
167    // `None` is interpreted as a missing field so be sure to implement `Some`
168    // as a present field.
169    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error>
170    where
171        V: serde::de::Visitor<'de>,
172    {
173        let original = self.input.original;
174        self.input
175            .root
176            .into_deserializer()
177            .deserialize_option(visitor)
178            .map_err(|mut e: Self::Error| {
179                e.inner.set_original(original);
180                e
181            })
182    }
183
184    fn deserialize_newtype_struct<V>(
185        self,
186        name: &'static str,
187        visitor: V,
188    ) -> Result<V::Value, Error>
189    where
190        V: serde::de::Visitor<'de>,
191    {
192        let original = self.input.original;
193        self.input
194            .root
195            .into_deserializer()
196            .deserialize_newtype_struct(name, visitor)
197            .map_err(|mut e: Self::Error| {
198                e.inner.set_original(original);
199                e
200            })
201    }
202
203    fn deserialize_struct<V>(
204        self,
205        name: &'static str,
206        fields: &'static [&'static str],
207        visitor: V,
208    ) -> Result<V::Value, Error>
209    where
210        V: serde::de::Visitor<'de>,
211    {
212        let original = self.input.original;
213        self.input
214            .root
215            .into_deserializer()
216            .deserialize_struct(name, fields, visitor)
217            .map_err(|mut e: Self::Error| {
218                e.inner.set_original(original);
219                e
220            })
221    }
222
223    // Called when the type to deserialize is an enum, as opposed to a field in the type.
224    fn deserialize_enum<V>(
225        self,
226        name: &'static str,
227        variants: &'static [&'static str],
228        visitor: V,
229    ) -> Result<V::Value, Error>
230    where
231        V: serde::de::Visitor<'de>,
232    {
233        let original = self.input.original;
234        self.input
235            .root
236            .into_deserializer()
237            .deserialize_enum(name, variants, visitor)
238            .map_err(|mut e: Self::Error| {
239                e.inner.set_original(original);
240                e
241            })
242    }
243
244    serde::forward_to_deserialize_any! {
245        bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq
246        bytes byte_buf map unit
247        ignored_any unit_struct tuple_struct tuple identifier
248    }
249}
250
251impl<'de> serde::de::IntoDeserializer<'de, crate::de::Error> for Deserializer {
252    type Deserializer = Deserializer;
253
254    fn into_deserializer(self) -> Self::Deserializer {
255        self
256    }
257}
258
259impl<'de> serde::de::IntoDeserializer<'de, crate::de::Error> for crate::Document {
260    type Deserializer = Deserializer;
261
262    fn into_deserializer(self) -> Self::Deserializer {
263        Deserializer::new(self)
264    }
265}
266
267pub(crate) fn validate_struct_keys(
268    table: &crate::table::KeyValuePairs,
269    fields: &'static [&'static str],
270) -> Result<(), Error> {
271    let extra_fields = table
272        .iter()
273        .filter_map(|(key, val)| {
274            if !fields.contains(&key.as_str()) {
275                Some(val.clone())
276            } else {
277                None
278            }
279        })
280        .collect::<Vec<_>>();
281
282    if extra_fields.is_empty() {
283        Ok(())
284    } else {
285        Err(Error::custom(
286            format!(
287                "unexpected keys in table: {}, available keys: {}",
288                extra_fields
289                    .iter()
290                    .map(|k| k.key.get())
291                    .collect::<Vec<_>>()
292                    .join(", "),
293                fields.join(", "),
294            ),
295            extra_fields[0].key.span(),
296        ))
297    }
298}