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