1use serde::de::IntoDeserializer as _;
2
3use crate::de::DatetimeDeserializer;
4use crate::de::Error;
5
6/// Deserialization implementation for TOML [values][crate::Value].
7///
8/// Can be creater 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/// ```
33pub struct ValueDeserializer {
34 input: crate::Item,
35 validate_struct_keys: bool,
36}
37
38impl ValueDeserializer {
39 pub(crate) fn new(input: crate::Item) -> Self {
40 Self {
41 input,
42 validate_struct_keys: false,
43 }
44 }
45
46 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
54impl<'de> serde::Deserializer<'de> for ValueDeserializer {
55 type Error = Error;
56
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.
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
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
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.
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
222impl<'de> serde::de::IntoDeserializer<'de, crate::de::Error> for ValueDeserializer {
223 type Deserializer = Self;
224
225 fn into_deserializer(self) -> Self::Deserializer {
226 self
227 }
228}
229
230impl<'de> serde::de::IntoDeserializer<'de, crate::de::Error> for crate::Value {
231 type Deserializer = ValueDeserializer;
232
233 fn into_deserializer(self) -> Self::Deserializer {
234 ValueDeserializer::new(input:crate::Item::Value(self))
235 }
236}
237
238impl crate::Item {
239 pub(crate) fn into_deserializer(self) -> ValueDeserializer {
240 ValueDeserializer::new(self)
241 }
242}
243
244impl std::str::FromStr for ValueDeserializer {
245 type Err = Error;
246
247 /// Parses a value from a &str
248 fn from_str(s: &str) -> Result<Self, Self::Err> {
249 let v: Value = crate::parser::parse_value(s).map_err(op:Error::from)?;
250 Ok(v.into_deserializer())
251 }
252}
253