toml/
de.rs

1//! Deserializing TOML into Rust structures.
2//!
3//! This module contains all the Serde support for deserializing TOML documents
4//! into Rust structures. Note that some top-level functions here are also
5//! provided at the top of the crate.
6
7/// Deserializes a string into a type.
8///
9/// This function will attempt to interpret `s` as a TOML document and
10/// deserialize `T` from the document.
11///
12/// To deserializes TOML values, instead of documents, see [`ValueDeserializer`].
13///
14/// # Examples
15///
16/// ```
17/// use serde::Deserialize;
18///
19/// #[derive(Deserialize)]
20/// struct Config {
21///     title: String,
22///     owner: Owner,
23/// }
24///
25/// #[derive(Deserialize)]
26/// struct Owner {
27///     name: String,
28/// }
29///
30/// let config: Config = toml::from_str(r#"
31///     title = 'TOML Example'
32///
33///     [owner]
34///     name = 'Lisa'
35/// "#).unwrap();
36///
37/// assert_eq!(config.title, "TOML Example");
38/// assert_eq!(config.owner.name, "Lisa");
39/// ```
40#[cfg(feature = "parse")]
41pub fn from_str<T>(s: &'_ str) -> Result<T, Error>
42where
43    T: serde::de::DeserializeOwned,
44{
45    T::deserialize(Deserializer::new(s))
46}
47
48/// Errors that can occur when deserializing a type.
49#[derive(Debug, PartialEq, Eq, Clone)]
50pub struct Error {
51    inner: crate::edit::de::Error,
52}
53
54impl Error {
55    fn new(inner: crate::edit::de::Error) -> Self {
56        Self { inner }
57    }
58
59    pub(crate) fn add_key(&mut self, key: String) {
60        self.inner.add_key(key)
61    }
62
63    /// What went wrong
64    pub fn message(&self) -> &str {
65        self.inner.message()
66    }
67
68    /// The start/end index into the original document where the error occurred
69    #[cfg(feature = "parse")]
70    pub fn span(&self) -> Option<std::ops::Range<usize>> {
71        self.inner.span()
72    }
73
74    /// Produces a (line, column) pair of the position of the error if available
75    ///
76    /// All indexes are 0-based.
77    #[deprecated(since = "0.18.0", note = "See instead `Error::span`")]
78    #[cfg(feature = "parse")]
79    pub fn line_col(&self) -> Option<(usize, usize)> {
80        #[allow(deprecated)]
81        self.inner.line_col()
82    }
83}
84
85impl serde::de::Error for Error {
86    fn custom<T>(msg: T) -> Self
87    where
88        T: std::fmt::Display,
89    {
90        Error::new(crate::edit::de::Error::custom(msg))
91    }
92}
93
94impl std::fmt::Display for Error {
95    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
96        self.inner.fmt(f)
97    }
98}
99
100impl std::error::Error for Error {}
101
102/// Deserialization TOML document
103///
104/// To deserializes TOML values, instead of documents, see [`ValueDeserializer`].
105#[cfg(feature = "parse")]
106pub struct Deserializer<'a> {
107    input: &'a str,
108}
109
110#[cfg(feature = "parse")]
111impl<'a> Deserializer<'a> {
112    /// Deserialization implementation for TOML.
113    pub fn new(input: &'a str) -> Self {
114        Self { input }
115    }
116}
117
118#[cfg(feature = "parse")]
119impl<'de, 'a> serde::Deserializer<'de> for Deserializer<'a> {
120    type Error = Error;
121
122    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
123    where
124        V: serde::de::Visitor<'de>,
125    {
126        let inner = self
127            .input
128            .parse::<toml_edit::de::Deserializer>()
129            .map_err(Error::new)?;
130        inner.deserialize_any(visitor).map_err(Error::new)
131    }
132
133    // `None` is interpreted as a missing field so be sure to implement `Some`
134    // as a present field.
135    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error>
136    where
137        V: serde::de::Visitor<'de>,
138    {
139        let inner = self
140            .input
141            .parse::<toml_edit::de::Deserializer>()
142            .map_err(Error::new)?;
143        inner.deserialize_option(visitor).map_err(Error::new)
144    }
145
146    fn deserialize_newtype_struct<V>(
147        self,
148        name: &'static str,
149        visitor: V,
150    ) -> Result<V::Value, Error>
151    where
152        V: serde::de::Visitor<'de>,
153    {
154        let inner = self
155            .input
156            .parse::<toml_edit::de::Deserializer>()
157            .map_err(Error::new)?;
158        inner
159            .deserialize_newtype_struct(name, visitor)
160            .map_err(Error::new)
161    }
162
163    fn deserialize_struct<V>(
164        self,
165        name: &'static str,
166        fields: &'static [&'static str],
167        visitor: V,
168    ) -> Result<V::Value, Error>
169    where
170        V: serde::de::Visitor<'de>,
171    {
172        let inner = self
173            .input
174            .parse::<toml_edit::de::Deserializer>()
175            .map_err(Error::new)?;
176        inner
177            .deserialize_struct(name, fields, visitor)
178            .map_err(Error::new)
179    }
180
181    // Called when the type to deserialize is an enum, as opposed to a field in the type.
182    fn deserialize_enum<V>(
183        self,
184        name: &'static str,
185        variants: &'static [&'static str],
186        visitor: V,
187    ) -> Result<V::Value, Error>
188    where
189        V: serde::de::Visitor<'de>,
190    {
191        let inner = self
192            .input
193            .parse::<toml_edit::de::Deserializer>()
194            .map_err(Error::new)?;
195        inner
196            .deserialize_enum(name, variants, visitor)
197            .map_err(Error::new)
198    }
199
200    serde::forward_to_deserialize_any! {
201        bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq
202        bytes byte_buf map unit
203        ignored_any unit_struct tuple_struct tuple identifier
204    }
205}
206
207/// Deserialization TOML [value][crate::Value]
208///
209/// # Example
210///
211/// ```
212/// use serde::Deserialize;
213///
214/// #[derive(Deserialize)]
215/// struct Config {
216///     title: String,
217///     owner: Owner,
218/// }
219///
220/// #[derive(Deserialize)]
221/// struct Owner {
222///     name: String,
223/// }
224///
225/// let config = Config::deserialize(toml::de::ValueDeserializer::new(
226///     r#"{ title = 'TOML Example', owner = { name = 'Lisa' } }"#
227/// )).unwrap();
228///
229/// assert_eq!(config.title, "TOML Example");
230/// assert_eq!(config.owner.name, "Lisa");
231/// ```
232#[cfg(feature = "parse")]
233pub struct ValueDeserializer<'a> {
234    input: &'a str,
235}
236
237#[cfg(feature = "parse")]
238impl<'a> ValueDeserializer<'a> {
239    /// Deserialization implementation for TOML.
240    pub fn new(input: &'a str) -> Self {
241        Self { input }
242    }
243}
244
245#[cfg(feature = "parse")]
246impl<'de, 'a> serde::Deserializer<'de> for ValueDeserializer<'a> {
247    type Error = Error;
248
249    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
250    where
251        V: serde::de::Visitor<'de>,
252    {
253        let inner = self
254            .input
255            .parse::<toml_edit::de::ValueDeserializer>()
256            .map_err(Error::new)?;
257        inner.deserialize_any(visitor).map_err(Error::new)
258    }
259
260    // `None` is interpreted as a missing field so be sure to implement `Some`
261    // as a present field.
262    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error>
263    where
264        V: serde::de::Visitor<'de>,
265    {
266        let inner = self
267            .input
268            .parse::<toml_edit::de::ValueDeserializer>()
269            .map_err(Error::new)?;
270        inner.deserialize_option(visitor).map_err(Error::new)
271    }
272
273    fn deserialize_newtype_struct<V>(
274        self,
275        name: &'static str,
276        visitor: V,
277    ) -> Result<V::Value, Error>
278    where
279        V: serde::de::Visitor<'de>,
280    {
281        let inner = self
282            .input
283            .parse::<toml_edit::de::ValueDeserializer>()
284            .map_err(Error::new)?;
285        inner
286            .deserialize_newtype_struct(name, visitor)
287            .map_err(Error::new)
288    }
289
290    fn deserialize_struct<V>(
291        self,
292        name: &'static str,
293        fields: &'static [&'static str],
294        visitor: V,
295    ) -> Result<V::Value, Error>
296    where
297        V: serde::de::Visitor<'de>,
298    {
299        let inner = self
300            .input
301            .parse::<toml_edit::de::ValueDeserializer>()
302            .map_err(Error::new)?;
303        inner
304            .deserialize_struct(name, fields, visitor)
305            .map_err(Error::new)
306    }
307
308    // Called when the type to deserialize is an enum, as opposed to a field in the type.
309    fn deserialize_enum<V>(
310        self,
311        name: &'static str,
312        variants: &'static [&'static str],
313        visitor: V,
314    ) -> Result<V::Value, Error>
315    where
316        V: serde::de::Visitor<'de>,
317    {
318        let inner = self
319            .input
320            .parse::<toml_edit::de::ValueDeserializer>()
321            .map_err(Error::new)?;
322        inner
323            .deserialize_enum(name, variants, visitor)
324            .map_err(Error::new)
325    }
326
327    serde::forward_to_deserialize_any! {
328        bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq
329        bytes byte_buf map unit
330        ignored_any unit_struct tuple_struct tuple identifier
331    }
332}