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