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