1 use serde::de::IntoDeserializer as _;
2 
3 use crate::de::DatetimeDeserializer;
4 use crate::de::Error;
5 
6 /// Deserialization implementation for TOML [values][crate::Value].
7 ///
8 /// Can be created either directly from TOML strings, using [`std::str::FromStr`],
9 /// or from parsed [values][crate::Value] using [`serde::de::IntoDeserializer::into_deserializer`].
10 ///
11 /// # Example
12 ///
13 /// ```
14 /// use serde::Deserialize;
15 ///
16 /// #[derive(Deserialize)]
17 /// struct Config {
18 ///     title: String,
19 ///     owner: Owner,
20 /// }
21 ///
22 /// #[derive(Deserialize)]
23 /// struct Owner {
24 ///     name: String,
25 /// }
26 ///
27 /// let value = r#"{ title = 'TOML Example', owner = { name = 'Lisa' } }"#;
28 /// let deserializer = value.parse::<toml_edit::de::ValueDeserializer>().unwrap();
29 /// let config = Config::deserialize(deserializer).unwrap();
30 /// assert_eq!(config.title, "TOML Example");
31 /// assert_eq!(config.owner.name, "Lisa");
32 /// ```
33 pub struct ValueDeserializer {
34     input: crate::Item,
35     validate_struct_keys: bool,
36 }
37 
38 impl ValueDeserializer {
new(input: crate::Item) -> Self39     pub(crate) fn new(input: crate::Item) -> Self {
40         Self {
41             input,
42             validate_struct_keys: false,
43         }
44     }
45 
with_struct_key_validation(mut self) -> Self46     pub(crate) fn with_struct_key_validation(mut self) -> Self {
47         self.validate_struct_keys = true;
48         self
49     }
50 }
51 
52 // Note: this is wrapped by `toml::de::ValueDeserializer` and any trait methods
53 // implemented here need to be wrapped there
54 impl<'de> serde::Deserializer<'de> for ValueDeserializer {
55     type Error = Error;
56 
deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: serde::de::Visitor<'de>,57     fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
58     where
59         V: serde::de::Visitor<'de>,
60     {
61         let span = self.input.span();
62         match self.input {
63             crate::Item::None => visitor.visit_none(),
64             crate::Item::Value(crate::Value::String(v)) => visitor.visit_string(v.into_value()),
65             crate::Item::Value(crate::Value::Integer(v)) => visitor.visit_i64(v.into_value()),
66             crate::Item::Value(crate::Value::Float(v)) => visitor.visit_f64(v.into_value()),
67             crate::Item::Value(crate::Value::Boolean(v)) => visitor.visit_bool(v.into_value()),
68             crate::Item::Value(crate::Value::Datetime(v)) => {
69                 visitor.visit_map(DatetimeDeserializer::new(v.into_value()))
70             }
71             crate::Item::Value(crate::Value::Array(v)) => {
72                 v.into_deserializer().deserialize_any(visitor)
73             }
74             crate::Item::Value(crate::Value::InlineTable(v)) => {
75                 v.into_deserializer().deserialize_any(visitor)
76             }
77             crate::Item::Table(v) => v.into_deserializer().deserialize_any(visitor),
78             crate::Item::ArrayOfTables(v) => v.into_deserializer().deserialize_any(visitor),
79         }
80         .map_err(|mut e: Self::Error| {
81             if e.span().is_none() {
82                 e.set_span(span);
83             }
84             e
85         })
86     }
87 
88     // `None` is interpreted as a missing field so be sure to implement `Some`
89     // as a present field.
deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error> where V: serde::de::Visitor<'de>,90     fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error>
91     where
92         V: serde::de::Visitor<'de>,
93     {
94         let span = self.input.span();
95         visitor.visit_some(self).map_err(|mut e: Self::Error| {
96             if e.span().is_none() {
97                 e.set_span(span);
98             }
99             e
100         })
101     }
102 
deserialize_newtype_struct<V>( self, _name: &'static str, visitor: V, ) -> Result<V::Value, Error> where V: serde::de::Visitor<'de>,103     fn deserialize_newtype_struct<V>(
104         self,
105         _name: &'static str,
106         visitor: V,
107     ) -> Result<V::Value, Error>
108     where
109         V: serde::de::Visitor<'de>,
110     {
111         let span = self.input.span();
112         visitor
113             .visit_newtype_struct(self)
114             .map_err(|mut e: Self::Error| {
115                 if e.span().is_none() {
116                     e.set_span(span);
117                 }
118                 e
119             })
120     }
121 
deserialize_struct<V>( self, name: &'static str, fields: &'static [&'static str], visitor: V, ) -> Result<V::Value, Error> where V: serde::de::Visitor<'de>,122     fn deserialize_struct<V>(
123         self,
124         name: &'static str,
125         fields: &'static [&'static str],
126         visitor: V,
127     ) -> Result<V::Value, Error>
128     where
129         V: serde::de::Visitor<'de>,
130     {
131         if serde_spanned::__unstable::is_spanned(name, fields) {
132             if let Some(span) = self.input.span() {
133                 return visitor.visit_map(super::SpannedDeserializer::new(self, span));
134             }
135         }
136 
137         if name == toml_datetime::__unstable::NAME && fields == [toml_datetime::__unstable::FIELD] {
138             let span = self.input.span();
139             if let crate::Item::Value(crate::Value::Datetime(d)) = self.input {
140                 return visitor
141                     .visit_map(DatetimeDeserializer::new(d.into_value()))
142                     .map_err(|mut e: Self::Error| {
143                         if e.span().is_none() {
144                             e.set_span(span);
145                         }
146                         e
147                     });
148             }
149         }
150 
151         if self.validate_struct_keys {
152             let span = self.input.span();
153             match &self.input {
154                 crate::Item::Table(values) => super::validate_struct_keys(&values.items, fields),
155                 crate::Item::Value(crate::Value::InlineTable(values)) => {
156                     super::validate_struct_keys(&values.items, fields)
157                 }
158                 _ => Ok(()),
159             }
160             .map_err(|mut e: Self::Error| {
161                 if e.span().is_none() {
162                     e.set_span(span);
163                 }
164                 e
165             })?
166         }
167 
168         self.deserialize_any(visitor)
169     }
170 
171     // 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>,172     fn deserialize_enum<V>(
173         self,
174         name: &'static str,
175         variants: &'static [&'static str],
176         visitor: V,
177     ) -> Result<V::Value, Error>
178     where
179         V: serde::de::Visitor<'de>,
180     {
181         let span = self.input.span();
182         match self.input {
183             crate::Item::Value(crate::Value::String(v)) => {
184                 visitor.visit_enum(v.into_value().into_deserializer())
185             }
186             crate::Item::Value(crate::Value::InlineTable(v)) => {
187                 if v.is_empty() {
188                     Err(crate::de::Error::custom(
189                         "wanted exactly 1 element, found 0 elements",
190                         v.span(),
191                     ))
192                 } else if v.len() != 1 {
193                     Err(crate::de::Error::custom(
194                         "wanted exactly 1 element, more than 1 element",
195                         v.span(),
196                     ))
197                 } else {
198                     v.into_deserializer()
199                         .deserialize_enum(name, variants, visitor)
200                 }
201             }
202             crate::Item::Table(v) => v
203                 .into_deserializer()
204                 .deserialize_enum(name, variants, visitor),
205             e => Err(crate::de::Error::custom("wanted string or table", e.span())),
206         }
207         .map_err(|mut e: Self::Error| {
208             if e.span().is_none() {
209                 e.set_span(span);
210             }
211             e
212         })
213     }
214 
215     serde::forward_to_deserialize_any! {
216         bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq
217         bytes byte_buf map unit
218         ignored_any unit_struct tuple_struct tuple identifier
219     }
220 }
221 
222 impl<'de> serde::de::IntoDeserializer<'de, crate::de::Error> for ValueDeserializer {
223     type Deserializer = Self;
224 
into_deserializer(self) -> Self::Deserializer225     fn into_deserializer(self) -> Self::Deserializer {
226         self
227     }
228 }
229 
230 impl<'de> serde::de::IntoDeserializer<'de, crate::de::Error> for crate::Value {
231     type Deserializer = ValueDeserializer;
232 
into_deserializer(self) -> Self::Deserializer233     fn into_deserializer(self) -> Self::Deserializer {
234         ValueDeserializer::new(crate::Item::Value(self))
235     }
236 }
237 
238 impl crate::Item {
into_deserializer(self) -> ValueDeserializer239     pub(crate) fn into_deserializer(self) -> ValueDeserializer {
240         ValueDeserializer::new(self)
241     }
242 }
243 
244 #[cfg(feature = "parse")]
245 impl std::str::FromStr for ValueDeserializer {
246     type Err = Error;
247 
248     /// Parses a value from a &str
from_str(s: &str) -> Result<Self, Self::Err>249     fn from_str(s: &str) -> Result<Self, Self::Err> {
250         let v = crate::parser::parse_value(s).map_err(Error::from)?;
251         Ok(v.into_deserializer())
252     }
253 }
254