Skip to main content

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_core::de::DeserializeOwned;
6
7mod array;
8mod error;
9mod key;
10mod table;
11mod table_enum;
12mod value;
13
14use array::ArrayDeserializer;
15use key::KeyDeserializer;
16use table::TableDeserializer;
17use table_enum::TableEnumDeserializer;
18use toml_datetime::de::DatetimeDeserializer;
19
20pub use error::Error;
21pub use value::ValueDeserializer;
22
23/// Deserializes a string into a type.
24///
25/// This function will attempt to interpret `s` as a TOML document and
26/// deserialize `T` from the document.
27///
28/// To deserializes TOML values, instead of documents, see [`ValueDeserializer`].
29///
30/// # Examples
31///
32/// ```
33/// use serde::Deserialize;
34///
35/// #[derive(Deserialize)]
36/// struct Config {
37///     title: String,
38///     owner: Owner,
39/// }
40///
41/// #[derive(Deserialize)]
42/// struct Owner {
43///     name: String,
44/// }
45///
46/// let config: Config = toml_edit::de::from_str(r#"
47///     title = 'TOML Example'
48///
49///     [owner]
50///     name = 'Lisa'
51/// "#).unwrap();
52///
53/// assert_eq!(config.title, "TOML Example");
54/// assert_eq!(config.owner.name, "Lisa");
55/// ```
56#[cfg(feature = "parse")]
57pub fn from_str<T>(s: &'_ str) -> Result<T, Error>
58where
59    T: DeserializeOwned,
60{
61    let de = Deserializer::parse(s)?;
62    T::deserialize(de)
63}
64
65/// Deserializes bytes into a type.
66///
67/// This function will attempt to interpret `s` as a TOML document and
68/// deserialize `T` from the document.
69///
70/// To deserializes TOML values, instead of documents, see [`ValueDeserializer`].
71#[cfg(feature = "parse")]
72pub fn from_slice<T>(s: &'_ [u8]) -> Result<T, Error>
73where
74    T: DeserializeOwned,
75{
76    let s = std::str::from_utf8(s).map_err(|e| Error::custom(e, None))?;
77    from_str(s)
78}
79
80/// Convert a [`DocumentMut`][crate::DocumentMut] into `T`.
81pub fn from_document<T>(d: impl Into<Deserializer>) -> Result<T, Error>
82where
83    T: DeserializeOwned,
84{
85    let deserializer = d.into();
86    T::deserialize(deserializer)
87}
88
89/// Deserialization for TOML [documents][crate::DocumentMut].
90pub struct Deserializer<S = String> {
91    root: crate::Item,
92    raw: Option<S>,
93}
94
95#[cfg(feature = "parse")]
96impl<S: AsRef<str>> Deserializer<S> {
97    /// Parse a TOML document
98    pub fn parse(raw: S) -> Result<Self, Error> {
99        crate::Document::parse(raw)
100            .map(Self::from)
101            .map_err(Into::into)
102    }
103}
104
105impl From<crate::DocumentMut> for Deserializer {
106    fn from(doc: crate::DocumentMut) -> Self {
107        let crate::DocumentMut { root, .. } = doc;
108        Self { root, raw: None }
109    }
110}
111
112impl<S> From<crate::Document<S>> for Deserializer<S> {
113    fn from(doc: crate::Document<S>) -> Self {
114        let crate::Document { root, raw, .. } = doc;
115        let raw = Some(raw);
116        Self { root, raw }
117    }
118}
119
120#[cfg(feature = "parse")]
121impl std::str::FromStr for Deserializer {
122    type Err = Error;
123
124    /// Parses a document from a &str
125    fn from_str(s: &str) -> Result<Self, Self::Err> {
126        let doc: crate::Document<_> = s.parse().map_err(Error::from)?;
127        Ok(Self::from(doc))
128    }
129}
130
131impl<'de, S: AsRef<str>> serde_core::Deserializer<'de> for Deserializer<S> {
132    type Error = Error;
133
134    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
135    where
136        V: serde_core::de::Visitor<'de>,
137    {
138        let raw = self.raw;
139        ValueDeserializer::new(self.root)
140            .deserialize_any(visitor)
141            .map_err(|mut e: Self::Error| {
142                let raw = raw.as_ref().map(|r| r.as_ref());
143                e.set_input(raw);
144                e
145            })
146    }
147
148    // `None` is interpreted as a missing field so be sure to implement `Some`
149    // as a present field.
150    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error>
151    where
152        V: serde_core::de::Visitor<'de>,
153    {
154        let raw = self.raw;
155        ValueDeserializer::new(self.root)
156            .deserialize_option(visitor)
157            .map_err(|mut e: Self::Error| {
158                let raw = raw.as_ref().map(|r| r.as_ref());
159                e.set_input(raw);
160                e
161            })
162    }
163
164    fn deserialize_newtype_struct<V>(
165        self,
166        name: &'static str,
167        visitor: V,
168    ) -> Result<V::Value, Error>
169    where
170        V: serde_core::de::Visitor<'de>,
171    {
172        let raw = self.raw;
173        ValueDeserializer::new(self.root)
174            .deserialize_newtype_struct(name, visitor)
175            .map_err(|mut e: Self::Error| {
176                let raw = raw.as_ref().map(|r| r.as_ref());
177                e.set_input(raw);
178                e
179            })
180    }
181
182    fn deserialize_struct<V>(
183        self,
184        name: &'static str,
185        fields: &'static [&'static str],
186        visitor: V,
187    ) -> Result<V::Value, Error>
188    where
189        V: serde_core::de::Visitor<'de>,
190    {
191        let raw = self.raw;
192        ValueDeserializer::new(self.root)
193            .deserialize_struct(name, fields, visitor)
194            .map_err(|mut e: Self::Error| {
195                let raw = raw.as_ref().map(|r| r.as_ref());
196                e.set_input(raw);
197                e
198            })
199    }
200
201    // Called when the type to deserialize is an enum, as opposed to a field in the type.
202    fn deserialize_enum<V>(
203        self,
204        name: &'static str,
205        variants: &'static [&'static str],
206        visitor: V,
207    ) -> Result<V::Value, Error>
208    where
209        V: serde_core::de::Visitor<'de>,
210    {
211        let raw = self.raw;
212        ValueDeserializer::new(self.root)
213            .deserialize_enum(name, variants, visitor)
214            .map_err(|mut e: Self::Error| {
215                let raw = raw.as_ref().map(|r| r.as_ref());
216                e.set_input(raw);
217                e
218            })
219    }
220
221    serde_core::forward_to_deserialize_any! {
222        bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq
223        bytes byte_buf map unit
224        ignored_any unit_struct tuple_struct tuple identifier
225    }
226}
227
228impl serde_core::de::IntoDeserializer<'_, Error> for Deserializer {
229    type Deserializer = Self;
230
231    fn into_deserializer(self) -> Self::Deserializer {
232        self
233    }
234}
235
236impl serde_core::de::IntoDeserializer<'_, Error> for crate::DocumentMut {
237    type Deserializer = Deserializer;
238
239    fn into_deserializer(self) -> Self::Deserializer {
240        Deserializer::from(self)
241    }
242}
243
244impl serde_core::de::IntoDeserializer<'_, Error> for crate::Document<String> {
245    type Deserializer = Deserializer;
246
247    fn into_deserializer(self) -> Self::Deserializer {
248        Deserializer::from(self)
249    }
250}