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