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