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