1use crate::error::{Error, Result};
20use crate::parse::{parse, Value};
21use indexmap::IndexMap;
22use serde::de::{
23 self, DeserializeOwned, DeserializeSeed, EnumAccess, IntoDeserializer, MapAccess, SeqAccess,
24 VariantAccess, Visitor,
25};
26
27pub fn from_str<T: DeserializeOwned>(input: &str) -> Result<T> {
56 let value = parse(input)?;
57 T::deserialize(ValueDeserializer(value))
58}
59
60struct ValueDeserializer(Value);
68
69impl<'de> de::Deserializer<'de> for ValueDeserializer {
70 type Error = Error;
71
72 fn deserialize_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
73 match self.0 {
74 Value::Scalar(s) => {
75 if s == "null" {
77 return visitor.visit_unit();
78 }
79 if s == "true" {
80 return visitor.visit_bool(true);
81 }
82 if s == "false" {
83 return visitor.visit_bool(false);
84 }
85 if let Ok(n) = s.parse::<i64>() {
86 return visitor.visit_i64(n);
87 }
88 if let Ok(n) = s.parse::<f64>() {
89 return visitor.visit_f64(n);
90 }
91 visitor.visit_string(s)
92 }
93 Value::Array(items) => visitor.visit_seq(SeqDe::new(items)),
94 Value::Object(map) => visitor.visit_map(MapDe::new(map)),
95 }
96 }
97
98 fn deserialize_bool<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
99 match &self.0 {
100 Value::Scalar(s) => match s.as_str() {
101 "true" => visitor.visit_bool(true),
102 "false" => visitor.visit_bool(false),
103 other => Err(Error::Parse(format!("expected bool, got '{other}'"))),
104 },
105 _ => Err(Error::Parse("expected scalar for bool".into())),
106 }
107 }
108
109 fn deserialize_i8<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
110 let n = parse_int(&self.0)?;
111 visitor.visit_i8(
112 i8::try_from(n).map_err(|_| Error::Parse(format!("value {n} out of range for i8")))?,
113 )
114 }
115
116 fn deserialize_i16<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
117 let n = parse_int(&self.0)?;
118 visitor.visit_i16(
119 i16::try_from(n)
120 .map_err(|_| Error::Parse(format!("value {n} out of range for i16")))?,
121 )
122 }
123
124 fn deserialize_i32<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
125 let n = parse_int(&self.0)?;
126 visitor.visit_i32(
127 i32::try_from(n)
128 .map_err(|_| Error::Parse(format!("value {n} out of range for i32")))?,
129 )
130 }
131
132 fn deserialize_i64<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
133 visitor.visit_i64(parse_int(&self.0)?)
134 }
135
136 fn deserialize_u8<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
137 let n = parse_uint(&self.0)?;
138 visitor.visit_u8(
139 u8::try_from(n).map_err(|_| Error::Parse(format!("value {n} out of range for u8")))?,
140 )
141 }
142
143 fn deserialize_u16<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
144 let n = parse_uint(&self.0)?;
145 visitor.visit_u16(
146 u16::try_from(n)
147 .map_err(|_| Error::Parse(format!("value {n} out of range for u16")))?,
148 )
149 }
150
151 fn deserialize_u32<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
152 let n = parse_uint(&self.0)?;
153 visitor.visit_u32(
154 u32::try_from(n)
155 .map_err(|_| Error::Parse(format!("value {n} out of range for u32")))?,
156 )
157 }
158
159 fn deserialize_u64<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
160 visitor.visit_u64(parse_uint(&self.0)?)
161 }
162
163 fn deserialize_f32<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
164 #[allow(clippy::cast_possible_truncation)]
166 visitor.visit_f32(parse_float(&self.0)? as f32)
167 }
168
169 fn deserialize_f64<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
170 visitor.visit_f64(parse_float(&self.0)?)
171 }
172
173 fn deserialize_char<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
174 if let Value::Scalar(s) = &self.0 {
175 let mut chars = s.chars();
176 if let Some(c) = chars.next() {
177 if chars.next().is_none() {
178 return visitor.visit_char(c);
179 }
180 }
181 }
182 Err(Error::Parse("expected single-character scalar".into()))
183 }
184
185 fn deserialize_str<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
186 if let Value::Scalar(s) = self.0 {
187 visitor.visit_string(s)
188 } else {
189 Err(Error::Parse("expected scalar string".into()))
190 }
191 }
192
193 fn deserialize_string<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
194 self.deserialize_str(visitor)
195 }
196
197 fn deserialize_bytes<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value> {
198 Err(Error::UnsupportedType("bytes"))
199 }
200
201 fn deserialize_byte_buf<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value> {
202 Err(Error::UnsupportedType("byte_buf"))
203 }
204
205 fn deserialize_option<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
206 if self.0.is_null() {
207 visitor.visit_none()
208 } else {
209 visitor.visit_some(self)
210 }
211 }
212
213 fn deserialize_unit<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
214 if self.0.is_null() {
215 visitor.visit_unit()
216 } else {
217 Err(Error::Parse(format!(
218 "expected null, found {}",
219 self.0.type_name()
220 )))
221 }
222 }
223
224 fn deserialize_unit_struct<V: Visitor<'de>>(
225 self,
226 _name: &'static str,
227 visitor: V,
228 ) -> Result<V::Value> {
229 self.deserialize_unit(visitor)
230 }
231
232 fn deserialize_newtype_struct<V: Visitor<'de>>(
233 self,
234 _name: &'static str,
235 visitor: V,
236 ) -> Result<V::Value> {
237 visitor.visit_newtype_struct(self)
238 }
239
240 fn deserialize_seq<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
241 match self.0 {
242 Value::Array(items) => visitor.visit_seq(SeqDe::new(items)),
243 _ => Err(Error::Parse("expected array value".into())),
244 }
245 }
246
247 fn deserialize_tuple<V: Visitor<'de>>(self, _len: usize, visitor: V) -> Result<V::Value> {
248 self.deserialize_seq(visitor)
249 }
250
251 fn deserialize_tuple_struct<V: Visitor<'de>>(
252 self,
253 _name: &'static str,
254 _len: usize,
255 visitor: V,
256 ) -> Result<V::Value> {
257 self.deserialize_seq(visitor)
258 }
259
260 fn deserialize_map<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
261 match self.0 {
262 Value::Object(map) => visitor.visit_map(MapDe::new(map)),
263 _ => Err(Error::Parse("expected object value".into())),
264 }
265 }
266
267 fn deserialize_struct<V: Visitor<'de>>(
268 self,
269 _name: &'static str,
270 _fields: &'static [&'static str],
271 visitor: V,
272 ) -> Result<V::Value> {
273 self.deserialize_map(visitor)
274 }
275
276 fn deserialize_enum<V: Visitor<'de>>(
277 self,
278 _name: &'static str,
279 _variants: &'static [&'static str],
280 visitor: V,
281 ) -> Result<V::Value> {
282 match self.0 {
283 Value::Scalar(s) => {
284 visitor.visit_enum(s.into_deserializer())
286 }
287 Value::Object(map) => {
288 if map.len() != 1 {
291 return Err(Error::Parse("enum object must have exactly one key".into()));
292 }
293 let (variant, payload) = map.into_iter().next().unwrap();
294 visitor.visit_enum(EnumDe { variant, payload })
295 }
296 Value::Array(_) => Err(Error::Parse("expected scalar or object for enum".into())),
297 }
298 }
299
300 fn deserialize_identifier<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
301 self.deserialize_str(visitor)
302 }
303
304 fn deserialize_ignored_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
305 self.deserialize_any(visitor)
306 }
307}
308
309struct SeqDe {
315 iter: std::vec::IntoIter<Value>,
316}
317
318impl SeqDe {
319 fn new(items: Vec<Value>) -> Self {
320 SeqDe {
321 iter: items.into_iter(),
322 }
323 }
324}
325
326impl<'de> SeqAccess<'de> for SeqDe {
327 type Error = Error;
328
329 fn next_element_seed<T: DeserializeSeed<'de>>(&mut self, seed: T) -> Result<Option<T::Value>> {
330 match self.iter.next() {
331 None => Ok(None),
332 Some(v) => seed.deserialize(ValueDeserializer(v)).map(Some),
333 }
334 }
335}
336
337struct MapDe {
343 iter: indexmap::map::IntoIter<String, Value>,
344 current_value: Option<Value>,
346}
347
348impl MapDe {
349 fn new(map: IndexMap<String, Value>) -> Self {
350 MapDe {
351 iter: map.into_iter(),
352 current_value: None,
353 }
354 }
355}
356
357impl<'de> MapAccess<'de> for MapDe {
358 type Error = Error;
359
360 fn next_key_seed<K: DeserializeSeed<'de>>(&mut self, seed: K) -> Result<Option<K::Value>> {
361 match self.iter.next() {
362 None => Ok(None),
363 Some((k, v)) => {
364 self.current_value = Some(v);
365 seed.deserialize(ValueDeserializer(Value::Scalar(k)))
366 .map(Some)
367 }
368 }
369 }
370
371 fn next_value_seed<V2: DeserializeSeed<'de>>(&mut self, seed: V2) -> Result<V2::Value> {
372 match self.current_value.take() {
373 None => Err(Error::Parse("value missing".into())),
374 Some(v) => seed.deserialize(ValueDeserializer(v)),
375 }
376 }
377}
378
379struct EnumDe {
385 variant: String,
387 payload: Value,
389}
390
391impl<'de> EnumAccess<'de> for EnumDe {
392 type Error = Error;
393 type Variant = VariantDe;
394
395 fn variant_seed<V: DeserializeSeed<'de>>(self, seed: V) -> Result<(V::Value, Self::Variant)> {
396 let variant_val = seed.deserialize(ValueDeserializer(Value::Scalar(self.variant)))?;
397 Ok((variant_val, VariantDe(self.payload)))
398 }
399}
400
401struct VariantDe(Value);
403
404impl<'de> VariantAccess<'de> for VariantDe {
405 type Error = Error;
406
407 fn unit_variant(self) -> Result<()> {
408 Ok(())
409 }
410
411 fn newtype_variant_seed<T: DeserializeSeed<'de>>(self, seed: T) -> Result<T::Value> {
412 seed.deserialize(ValueDeserializer(self.0))
413 }
414
415 fn tuple_variant<V: Visitor<'de>>(self, _len: usize, visitor: V) -> Result<V::Value> {
416 de::Deserializer::deserialize_seq(ValueDeserializer(self.0), visitor)
417 }
418
419 fn struct_variant<V: Visitor<'de>>(
420 self,
421 _fields: &'static [&'static str],
422 visitor: V,
423 ) -> Result<V::Value> {
424 de::Deserializer::deserialize_map(ValueDeserializer(self.0), visitor)
425 }
426}
427
428fn parse_int(v: &Value) -> Result<i64> {
438 if let Value::Scalar(s) = v {
439 s.parse::<i64>()
440 .map_err(|_| Error::Parse(format!("expected integer, got '{s}'")))
441 } else {
442 Err(Error::Parse("expected scalar for integer".into()))
443 }
444}
445
446fn parse_uint(v: &Value) -> Result<u64> {
452 if let Value::Scalar(s) = v {
453 s.parse::<u64>()
454 .map_err(|_| Error::Parse(format!("expected unsigned integer, got '{s}'")))
455 } else {
456 Err(Error::Parse("expected scalar for unsigned integer".into()))
457 }
458}
459
460fn parse_float(v: &Value) -> Result<f64> {
466 if let Value::Scalar(s) = v {
467 s.parse::<f64>()
468 .map_err(|_| Error::Parse(format!("expected float, got '{s}'")))
469 } else {
470 Err(Error::Parse("expected scalar for float".into()))
471 }
472}