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