1use crate::error::{Error, ErrorKind};
2use crate::parser::{loads, Top};
3use crate::value::Value;
4
5use serde::de::{self, DeserializeSeed, IntoDeserializer, MapAccess, SeqAccess, Visitor};
6use serde::Deserialize;
7
8pub fn from_str<'de, T: Deserialize<'de>>(s: &'de str) -> Result<T, Error> {
13 let value = loads(s, Top::Any)?.unwrap_or(Value::String(String::new()));
14 T::deserialize(ValueDeserializer { value: &value })
15}
16
17struct ValueDeserializer<'a> {
18 value: &'a Value,
19}
20
21impl<'de, 'a> de::Deserializer<'de> for ValueDeserializer<'a> {
22 type Error = Error;
23
24 fn deserialize_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
25 match self.value {
26 Value::String(s) => visitor.visit_str(s),
27 Value::List(_) => self.deserialize_seq(visitor),
28 Value::Dict(_) => self.deserialize_map(visitor),
29 }
30 }
31
32 fn deserialize_bool<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
33 match self.value {
34 Value::String(s) => match s.as_str() {
35 "true" | "True" | "TRUE" | "yes" | "Yes" | "YES" => visitor.visit_bool(true),
36 "false" | "False" | "FALSE" | "no" | "No" | "NO" => visitor.visit_bool(false),
37 _ => Err(Error::new(
38 ErrorKind::UnsupportedType,
39 format!("cannot parse '{}' as boolean", s),
40 )),
41 },
42 _ => Err(Error::new(
43 ErrorKind::UnsupportedType,
44 "expected string for boolean",
45 )),
46 }
47 }
48
49 fn deserialize_i8<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
50 let s = self.expect_string()?;
51 let n: i8 = s.parse().map_err(|_| {
52 Error::new(ErrorKind::UnsupportedType, format!("cannot parse '{}' as i8", s))
53 })?;
54 visitor.visit_i8(n)
55 }
56
57 fn deserialize_i16<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
58 let s = self.expect_string()?;
59 let n: i16 = s.parse().map_err(|_| {
60 Error::new(ErrorKind::UnsupportedType, format!("cannot parse '{}' as i16", s))
61 })?;
62 visitor.visit_i16(n)
63 }
64
65 fn deserialize_i32<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
66 let s = self.expect_string()?;
67 let n: i32 = s.parse().map_err(|_| {
68 Error::new(ErrorKind::UnsupportedType, format!("cannot parse '{}' as i32", s))
69 })?;
70 visitor.visit_i32(n)
71 }
72
73 fn deserialize_i64<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
74 let s = self.expect_string()?;
75 let n: i64 = s.parse().map_err(|_| {
76 Error::new(ErrorKind::UnsupportedType, format!("cannot parse '{}' as i64", s))
77 })?;
78 visitor.visit_i64(n)
79 }
80
81 fn deserialize_u8<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
82 let s = self.expect_string()?;
83 let n: u8 = s.parse().map_err(|_| {
84 Error::new(ErrorKind::UnsupportedType, format!("cannot parse '{}' as u8", s))
85 })?;
86 visitor.visit_u8(n)
87 }
88
89 fn deserialize_u16<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
90 let s = self.expect_string()?;
91 let n: u16 = s.parse().map_err(|_| {
92 Error::new(ErrorKind::UnsupportedType, format!("cannot parse '{}' as u16", s))
93 })?;
94 visitor.visit_u16(n)
95 }
96
97 fn deserialize_u32<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
98 let s = self.expect_string()?;
99 let n: u32 = s.parse().map_err(|_| {
100 Error::new(ErrorKind::UnsupportedType, format!("cannot parse '{}' as u32", s))
101 })?;
102 visitor.visit_u32(n)
103 }
104
105 fn deserialize_u64<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
106 let s = self.expect_string()?;
107 let n: u64 = s.parse().map_err(|_| {
108 Error::new(ErrorKind::UnsupportedType, format!("cannot parse '{}' as u64", s))
109 })?;
110 visitor.visit_u64(n)
111 }
112
113 fn deserialize_f32<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
114 let s = self.expect_string()?;
115 let n: f32 = s.parse().map_err(|_| {
116 Error::new(ErrorKind::UnsupportedType, format!("cannot parse '{}' as f32", s))
117 })?;
118 visitor.visit_f32(n)
119 }
120
121 fn deserialize_f64<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
122 let s = self.expect_string()?;
123 let n: f64 = s.parse().map_err(|_| {
124 Error::new(ErrorKind::UnsupportedType, format!("cannot parse '{}' as f64", s))
125 })?;
126 visitor.visit_f64(n)
127 }
128
129 fn deserialize_char<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
130 let s = self.expect_string()?;
131 let mut chars = s.chars();
132 let c = chars.next().ok_or_else(|| {
133 Error::new(ErrorKind::UnsupportedType, "empty string for char")
134 })?;
135 if chars.next().is_some() {
136 return Err(Error::new(
137 ErrorKind::UnsupportedType,
138 "expected single character",
139 ));
140 }
141 visitor.visit_char(c)
142 }
143
144 fn deserialize_str<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
145 let s = self.expect_string()?;
146 visitor.visit_str(s)
147 }
148
149 fn deserialize_string<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
150 let s = self.expect_string()?;
151 visitor.visit_string(s.to_string())
152 }
153
154 fn deserialize_bytes<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value, Error> {
155 Err(Error::new(
156 ErrorKind::UnsupportedType,
157 "NestedText does not support byte arrays",
158 ))
159 }
160
161 fn deserialize_byte_buf<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value, Error> {
162 Err(Error::new(
163 ErrorKind::UnsupportedType,
164 "NestedText does not support byte arrays",
165 ))
166 }
167
168 fn deserialize_option<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
169 match self.value {
171 Value::String(s) if s.is_empty() => visitor.visit_none(),
172 _ => visitor.visit_some(self),
173 }
174 }
175
176 fn deserialize_unit<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
177 match self.value {
178 Value::String(s) if s.is_empty() => visitor.visit_unit(),
179 _ => Err(Error::new(
180 ErrorKind::UnsupportedType,
181 "expected empty string for unit",
182 )),
183 }
184 }
185
186 fn deserialize_unit_struct<V: Visitor<'de>>(
187 self,
188 _name: &'static str,
189 visitor: V,
190 ) -> Result<V::Value, Error> {
191 self.deserialize_unit(visitor)
192 }
193
194 fn deserialize_newtype_struct<V: Visitor<'de>>(
195 self,
196 _name: &'static str,
197 visitor: V,
198 ) -> Result<V::Value, Error> {
199 visitor.visit_newtype_struct(self)
200 }
201
202 fn deserialize_seq<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
203 match self.value {
204 Value::List(items) => visitor.visit_seq(SeqDeserializer {
205 iter: items.iter(),
206 }),
207 _ => Err(Error::new(
208 ErrorKind::UnsupportedType,
209 "expected list for sequence",
210 )),
211 }
212 }
213
214 fn deserialize_tuple<V: Visitor<'de>>(self, _len: usize, visitor: V) -> Result<V::Value, Error> {
215 self.deserialize_seq(visitor)
216 }
217
218 fn deserialize_tuple_struct<V: Visitor<'de>>(
219 self,
220 _name: &'static str,
221 _len: usize,
222 visitor: V,
223 ) -> Result<V::Value, Error> {
224 self.deserialize_seq(visitor)
225 }
226
227 fn deserialize_map<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
228 match self.value {
229 Value::Dict(pairs) => visitor.visit_map(MapDeserializer {
230 iter: pairs.iter(),
231 next_value: None,
232 }),
233 _ => Err(Error::new(
234 ErrorKind::UnsupportedType,
235 "expected dictionary for map",
236 )),
237 }
238 }
239
240 fn deserialize_struct<V: Visitor<'de>>(
241 self,
242 _name: &'static str,
243 _fields: &'static [&'static str],
244 visitor: V,
245 ) -> Result<V::Value, Error> {
246 self.deserialize_map(visitor)
247 }
248
249 fn deserialize_enum<V: Visitor<'de>>(
250 self,
251 _name: &'static str,
252 _variants: &'static [&'static str],
253 visitor: V,
254 ) -> Result<V::Value, Error> {
255 match self.value {
256 Value::String(s) => visitor.visit_enum(s.as_str().into_deserializer()),
258 Value::Dict(pairs) => {
260 if pairs.len() != 1 {
261 return Err(Error::new(
262 ErrorKind::UnsupportedType,
263 "enum must be a string or single-key dictionary",
264 ));
265 }
266 let (variant, value) = &pairs[0];
267 visitor.visit_enum(EnumDeserializer {
268 variant,
269 value,
270 })
271 }
272 _ => Err(Error::new(
273 ErrorKind::UnsupportedType,
274 "expected string or dictionary for enum",
275 )),
276 }
277 }
278
279 fn deserialize_identifier<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
280 self.deserialize_str(visitor)
281 }
282
283 fn deserialize_ignored_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
284 self.deserialize_any(visitor)
285 }
286}
287
288impl<'a> ValueDeserializer<'a> {
289 fn expect_string(&self) -> Result<&'a str, Error> {
290 match self.value {
291 Value::String(s) => Ok(s.as_str()),
292 _ => Err(Error::new(
293 ErrorKind::UnsupportedType,
294 "expected string value",
295 )),
296 }
297 }
298}
299
300struct SeqDeserializer<'a> {
302 iter: std::slice::Iter<'a, Value>,
303}
304
305impl<'de, 'a> SeqAccess<'de> for SeqDeserializer<'a> {
306 type Error = Error;
307
308 fn next_element_seed<T: DeserializeSeed<'de>>(
309 &mut self,
310 seed: T,
311 ) -> Result<Option<T::Value>, Error> {
312 match self.iter.next() {
313 Some(value) => seed
314 .deserialize(ValueDeserializer { value })
315 .map(Some),
316 None => Ok(None),
317 }
318 }
319}
320
321struct MapDeserializer<'a> {
323 iter: std::slice::Iter<'a, (String, Value)>,
324 next_value: Option<&'a Value>,
325}
326
327impl<'de, 'a> MapAccess<'de> for MapDeserializer<'a> {
328 type Error = Error;
329
330 fn next_key_seed<K: DeserializeSeed<'de>>(
331 &mut self,
332 seed: K,
333 ) -> Result<Option<K::Value>, Error> {
334 match self.iter.next() {
335 Some((key, value)) => {
336 self.next_value = Some(value);
337 let key_value = Value::String(key.clone());
338 seed.deserialize(ValueDeserializer { value: &key_value })
339 .map(Some)
340 }
341 None => Ok(None),
342 }
343 }
344
345 fn next_value_seed<V: DeserializeSeed<'de>>(
346 &mut self,
347 seed: V,
348 ) -> Result<V::Value, Error> {
349 let value = self.next_value.take().expect("next_value called before next_key");
350 seed.deserialize(ValueDeserializer { value })
351 }
352}
353
354struct EnumDeserializer<'a> {
356 variant: &'a str,
357 value: &'a Value,
358}
359
360impl<'de, 'a> de::EnumAccess<'de> for EnumDeserializer<'a> {
361 type Error = Error;
362 type Variant = VariantDeserializer<'a>;
363
364 fn variant_seed<V: DeserializeSeed<'de>>(
365 self,
366 seed: V,
367 ) -> Result<(V::Value, Self::Variant), Error> {
368 let variant_value = Value::String(self.variant.to_string());
369 let v = seed.deserialize(ValueDeserializer {
370 value: &variant_value,
371 })?;
372 Ok((v, VariantDeserializer { value: self.value }))
373 }
374}
375
376struct VariantDeserializer<'a> {
377 value: &'a Value,
378}
379
380impl<'de, 'a> de::VariantAccess<'de> for VariantDeserializer<'a> {
381 type Error = Error;
382
383 fn unit_variant(self) -> Result<(), Error> {
384 Ok(())
385 }
386
387 fn newtype_variant_seed<T: DeserializeSeed<'de>>(
388 self,
389 seed: T,
390 ) -> Result<T::Value, Error> {
391 seed.deserialize(ValueDeserializer { value: self.value })
392 }
393
394 fn tuple_variant<V: Visitor<'de>>(self, _len: usize, visitor: V) -> Result<V::Value, Error> {
395 match self.value {
396 Value::List(items) => visitor.visit_seq(SeqDeserializer {
397 iter: items.iter(),
398 }),
399 _ => Err(Error::new(
400 ErrorKind::UnsupportedType,
401 "expected list for tuple variant",
402 )),
403 }
404 }
405
406 fn struct_variant<V: Visitor<'de>>(
407 self,
408 _fields: &'static [&'static str],
409 visitor: V,
410 ) -> Result<V::Value, Error> {
411 match self.value {
412 Value::Dict(pairs) => visitor.visit_map(MapDeserializer {
413 iter: pairs.iter(),
414 next_value: None,
415 }),
416 _ => Err(Error::new(
417 ErrorKind::UnsupportedType,
418 "expected dictionary for struct variant",
419 )),
420 }
421 }
422}
423
424impl de::Error for Error {
426 fn custom<T: std::fmt::Display>(msg: T) -> Self {
427 Error::new(ErrorKind::UnsupportedType, msg.to_string())
428 }
429}
430
431#[cfg(test)]
432mod tests {
433 use super::*;
434 use serde::Deserialize;
435
436 #[test]
437 fn test_deserialize_struct() {
438 #[derive(Deserialize, Debug, PartialEq)]
439 struct Config {
440 name: String,
441 age: u32,
442 }
443 let input = "name: Alice\nage: 30";
444 let config: Config = from_str(input).unwrap();
445 assert_eq!(
446 config,
447 Config {
448 name: "Alice".to_string(),
449 age: 30,
450 }
451 );
452 }
453
454 #[test]
455 fn test_deserialize_vec() {
456 let input = "- hello\n- world";
457 let v: Vec<String> = from_str(input).unwrap();
458 assert_eq!(v, vec!["hello", "world"]);
459 }
460
461 #[test]
462 fn test_deserialize_nested() {
463 #[derive(Deserialize, Debug, PartialEq)]
464 struct Outer {
465 items: Vec<String>,
466 }
467 let input = "items:\n - a\n - b";
468 let v: Outer = from_str(input).unwrap();
469 assert_eq!(
470 v,
471 Outer {
472 items: vec!["a".to_string(), "b".to_string()],
473 }
474 );
475 }
476
477 #[test]
478 fn test_deserialize_bool() {
479 #[derive(Deserialize, Debug, PartialEq)]
480 struct Flags {
481 debug: bool,
482 verbose: bool,
483 }
484 let input = "debug: true\nverbose: false";
485 let v: Flags = from_str(input).unwrap();
486 assert_eq!(
487 v,
488 Flags {
489 debug: true,
490 verbose: false,
491 }
492 );
493 }
494
495 #[test]
496 fn test_deserialize_option() {
497 #[derive(Deserialize, Debug, PartialEq)]
498 struct MaybeValue {
499 present: Option<String>,
500 absent: Option<String>,
501 }
502 let input = "present: hello\nabsent:";
503 let v: MaybeValue = from_str(input).unwrap();
504 assert_eq!(
505 v,
506 MaybeValue {
507 present: Some("hello".to_string()),
508 absent: None,
509 }
510 );
511 }
512
513 #[test]
514 fn test_deserialize_enum() {
515 #[derive(Deserialize, Debug, PartialEq)]
516 enum Color {
517 Red,
518 Green,
519 Blue,
520 }
521 let input = "> Red";
522 let v: Color = from_str(input).unwrap();
523 assert_eq!(v, Color::Red);
524 }
525
526 #[test]
527 fn test_deserialize_hashmap() {
528 use std::collections::HashMap;
529 let input = "a: 1\nb: 2";
530 let v: HashMap<String, String> = from_str(input).unwrap();
531 assert_eq!(v.get("a").unwrap(), "1");
532 assert_eq!(v.get("b").unwrap(), "2");
533 }
534}