use crate::deserialize::{literal, Item};
use crate::error::Result;
use crate::DeserializeError;
use nom::Finish;
use serde::Deserialize;
mod iterators;
mod deserialize;
mod sequence_deserializer;
mod map_deserializer;
mod enum_deserializer;
use crate::deserialize::adapter::iterators::{DynIndexTracker, DynIter, IterAdapter, IterClone};
pub use deserialize::Deserializer;
pub fn from_str<'a, T: Deserialize<'a>>(input: &str) -> Result<T, DeserializeError<&str>> {
match literal(input).finish()?.1 {
Item::List(items) => {
Ok(T::deserialize(&mut Deserializer::new(items.into_iter()))?)
},
_ => Err(DeserializeError::ExpectedList)
}
}
#[test]
fn test_map() {
use std::collections::HashMap;
let mut expected = HashMap::new();
expected.insert("a".to_string(), 1);
expected.insert("b".to_string(), 2);
assert_eq!(
from_str::<HashMap<String, i32>>(r#"(a(1),b(2))"#).unwrap(),
expected
);
}
#[test]
fn test_struct() {
#[derive(Deserialize)]
#[derive(Debug)]
#[derive(PartialEq)]
struct Test {
int: u32,
seq: Vec<String>,
nested: Option<Box<Self>>
}
let expected = Test {
int: 1,
seq: vec!["a".into(), "b".into()],
nested: Some(Box::new(Test {
int: 50,
seq: vec!["c".into(), "d".into()],
nested: None,
})),
};
assert_eq!(from_str::<Test>(r#"(
int(
1
)
seq(
a,b
)
nested(
int(50),
seq(c,d),
nested(null)
)
)"#).unwrap(), expected);
}
#[test]
fn test_enum() {
#[derive(Deserialize)]
#[derive(Debug)]
#[derive(PartialEq)]
enum E {
Unit,
Newtype(u32),
Tuple(u32, u32),
Struct { a: u32, b: u32 },
}
let expected = E::Unit;
assert_eq!(from_str::<E>(r#"(Unit)"#).unwrap(), expected);
let expected = E::Newtype(1);
assert_eq!(from_str::<E>(r#"(Newtype(1))"#).unwrap(), expected);
let expected = E::Tuple(1, 2);
assert_eq!(from_str::<E>(r#"(Tuple(1,2))"#).unwrap(), expected);
let expected = E::Struct { a: 1, b: 5 };
assert_eq!(from_str::<E>(r#"(Struct(a(1),b(5)))"#).unwrap(), expected);
}
pub fn from_iter<'a, T: Deserialize<'a>, I: IterClone<'a, char> + 'a>(iter: I) -> Result<T, DeserializeError<IterAdapter<'a, char>>> {
match literal(
IterAdapter {
inner: DynIndexTracker {
inner: DynIter {
inner: Box::new(iter),
}.enumerate(),
index: 0,
length: 0,
},
}
).finish()?.1 {
Item::List(items) => {
Ok(T::deserialize(&mut Deserializer::new(items.into_iter()))?)
},
_ => Err(DeserializeError::ExpectedList)
}
}