1use serde::de::IntoDeserializer as _;
2
3use crate::de::DatetimeDeserializer;
4use crate::de::Error;
5
6pub struct ValueDeserializer {
32 input: crate::Item,
33 validate_struct_keys: bool,
34}
35
36impl ValueDeserializer {
37 pub(crate) fn new(input: crate::Item) -> Self {
38 Self {
39 input,
40 validate_struct_keys: false,
41 }
42 }
43
44 pub(crate) fn with_struct_key_validation(mut self) -> Self {
45 self.validate_struct_keys = true;
46 self
47 }
48}
49
50impl<'de> serde::Deserializer<'de> for ValueDeserializer {
53 type Error = Error;
54
55 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
56 where
57 V: serde::de::Visitor<'de>,
58 {
59 let span = self.input.span();
60 match self.input {
61 crate::Item::None => visitor.visit_none(),
62 crate::Item::Value(crate::Value::String(v)) => visitor.visit_string(v.into_value()),
63 crate::Item::Value(crate::Value::Integer(v)) => visitor.visit_i64(v.into_value()),
64 crate::Item::Value(crate::Value::Float(v)) => visitor.visit_f64(v.into_value()),
65 crate::Item::Value(crate::Value::Boolean(v)) => visitor.visit_bool(v.into_value()),
66 crate::Item::Value(crate::Value::Datetime(v)) => {
67 visitor.visit_map(DatetimeDeserializer::new(v.into_value()))
68 }
69 crate::Item::Value(crate::Value::Array(v)) => {
70 v.into_deserializer().deserialize_any(visitor)
71 }
72 crate::Item::Value(crate::Value::InlineTable(v)) => {
73 v.into_deserializer().deserialize_any(visitor)
74 }
75 crate::Item::Table(v) => v.into_deserializer().deserialize_any(visitor),
76 crate::Item::ArrayOfTables(v) => v.into_deserializer().deserialize_any(visitor),
77 }
78 .map_err(|mut e: Self::Error| {
79 if e.span().is_none() {
80 e.set_span(span);
81 }
82 e
83 })
84 }
85
86 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error>
89 where
90 V: serde::de::Visitor<'de>,
91 {
92 let span = self.input.span();
93 visitor.visit_some(self).map_err(|mut e: Self::Error| {
94 if e.span().is_none() {
95 e.set_span(span);
96 }
97 e
98 })
99 }
100
101 fn deserialize_newtype_struct<V>(
102 self,
103 _name: &'static str,
104 visitor: V,
105 ) -> Result<V::Value, Error>
106 where
107 V: serde::de::Visitor<'de>,
108 {
109 let span = self.input.span();
110 visitor
111 .visit_newtype_struct(self)
112 .map_err(|mut e: Self::Error| {
113 if e.span().is_none() {
114 e.set_span(span);
115 }
116 e
117 })
118 }
119
120 fn deserialize_struct<V>(
121 self,
122 name: &'static str,
123 fields: &'static [&'static str],
124 visitor: V,
125 ) -> Result<V::Value, Error>
126 where
127 V: serde::de::Visitor<'de>,
128 {
129 if serde_spanned::__unstable::is_spanned(name, fields) {
130 if let Some(span) = self.input.span() {
131 return visitor.visit_map(super::SpannedDeserializer::new(self, span));
132 }
133 }
134
135 if name == toml_datetime::__unstable::NAME && fields == [toml_datetime::__unstable::FIELD] {
136 let span = self.input.span();
137 if let crate::Item::Value(crate::Value::Datetime(d)) = self.input {
138 return visitor
139 .visit_map(DatetimeDeserializer::new(d.into_value()))
140 .map_err(|mut e: Self::Error| {
141 if e.span().is_none() {
142 e.set_span(span);
143 }
144 e
145 });
146 }
147 }
148
149 if self.validate_struct_keys {
150 let span = self.input.span();
151 match &self.input {
152 crate::Item::Table(values) => super::validate_struct_keys(&values.items, fields),
153 crate::Item::Value(crate::Value::InlineTable(values)) => {
154 super::validate_struct_keys(&values.items, fields)
155 }
156 _ => Ok(()),
157 }
158 .map_err(|mut e: Self::Error| {
159 if e.span().is_none() {
160 e.set_span(span);
161 }
162 e
163 })?
164 }
165
166 self.deserialize_any(visitor)
167 }
168
169 fn deserialize_enum<V>(
171 self,
172 name: &'static str,
173 variants: &'static [&'static str],
174 visitor: V,
175 ) -> Result<V::Value, Error>
176 where
177 V: serde::de::Visitor<'de>,
178 {
179 let span = self.input.span();
180 match self.input {
181 crate::Item::Value(crate::Value::String(v)) => {
182 visitor.visit_enum(v.into_value().into_deserializer())
183 }
184 crate::Item::Value(crate::Value::InlineTable(v)) => {
185 if v.is_empty() {
186 Err(crate::de::Error::custom(
187 "wanted exactly 1 element, found 0 elements",
188 v.span(),
189 ))
190 } else if v.len() != 1 {
191 Err(crate::de::Error::custom(
192 "wanted exactly 1 element, more than 1 element",
193 v.span(),
194 ))
195 } else {
196 v.into_deserializer()
197 .deserialize_enum(name, variants, visitor)
198 }
199 }
200 crate::Item::Table(v) => v
201 .into_deserializer()
202 .deserialize_enum(name, variants, visitor),
203 e => Err(crate::de::Error::custom("wanted string or table", e.span())),
204 }
205 .map_err(|mut e: Self::Error| {
206 if e.span().is_none() {
207 e.set_span(span);
208 }
209 e
210 })
211 }
212
213 serde::forward_to_deserialize_any! {
214 bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq
215 bytes byte_buf map unit
216 ignored_any unit_struct tuple_struct tuple identifier
217 }
218}
219
220impl<'de> serde::de::IntoDeserializer<'de, crate::de::Error> for ValueDeserializer {
221 type Deserializer = Self;
222
223 fn into_deserializer(self) -> Self::Deserializer {
224 self
225 }
226}
227
228impl<'de> serde::de::IntoDeserializer<'de, crate::de::Error> for crate::Value {
229 type Deserializer = ValueDeserializer;
230
231 fn into_deserializer(self) -> Self::Deserializer {
232 ValueDeserializer::new(crate::Item::Value(self))
233 }
234}
235
236impl crate::Item {
237 pub(crate) fn into_deserializer(self) -> ValueDeserializer {
238 ValueDeserializer::new(self)
239 }
240}
241
242impl std::str::FromStr for ValueDeserializer {
243 type Err = Error;
244
245 fn from_str(s: &str) -> Result<Self, Self::Err> {
247 let v = crate::parser::parse_value(s).map_err(Error::from)?;
248 Ok(v.into_deserializer())
249 }
250}