mod mapkey;
mod reference;
mod value;
use serde::de;
use std::{fmt, result};
use crate::value::{UniNode, Object, Array};
struct UniNodeVisitor;
type VResult<E> = result::Result<UniNode, E>;
impl<'de> de::Visitor<'de> for UniNodeVisitor {
type Value = UniNode;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("any valid UniNode value")
}
fn visit_bool<E>(self, v: bool) -> VResult<E> {
Ok(UniNode::from(v))
}
fn visit_i8<E>(self, v: i8) -> VResult<E> {
Ok(UniNode::from(v))
}
fn visit_i16<E>(self, v: i16) -> VResult<E> {
Ok(UniNode::from(v))
}
fn visit_i32<E>(self, v: i32) -> VResult<E> {
Ok(UniNode::from(v))
}
fn visit_i64<E>(self, v: i64) -> VResult<E> {
Ok(UniNode::from(v))
}
fn visit_u8<E>(self, v: u8) -> VResult<E> {
Ok(UniNode::from(v))
}
fn visit_u16<E>(self, v: u16) -> VResult<E> {
Ok(UniNode::from(v))
}
fn visit_u32<E>(self, v: u32) -> VResult<E> {
Ok(UniNode::from(v))
}
fn visit_u64<E>(self, v: u64) -> VResult<E> {
Ok(UniNode::from(v))
}
fn visit_f32<E>(self, v: f32) -> VResult<E> {
Ok(UniNode::from(v))
}
fn visit_f64<E>(self, v: f64) -> VResult<E> {
Ok(UniNode::from(v))
}
fn visit_str<E>(self, v: &str) -> VResult<E> {
Ok(UniNode::from(v))
}
fn visit_string<E>(self, v: String) -> VResult<E> {
Ok(UniNode::from(v))
}
fn visit_none<E>(self) -> VResult<E> {
Ok(UniNode::Null)
}
fn visit_unit<E>(self) -> VResult<E> {
Ok(UniNode::Null)
}
fn visit_bytes<E>(self, v: &[u8]) -> VResult<E> {
Ok(UniNode::from(v))
}
fn visit_byte_buf<E>(self, v: Vec<u8>) -> VResult<E> {
Ok(UniNode::from(v))
}
fn visit_some<D>(self, deserializer: D) -> VResult<D::Error>
where
D: de::Deserializer<'de>,
{
deserializer.deserialize_any(self)
}
fn visit_seq<A>(self, mut seq: A) -> VResult<A::Error>
where
A: de::SeqAccess<'de>,
{
let mut vec = Array::with_capacity(seq.size_hint().unwrap_or(0));
while let Some(el) = seq.next_element()? {
vec.push(el);
}
Ok(UniNode::Array(vec))
}
fn visit_map<A>(self, mut map: A) -> VResult<A::Error>
where
A: de::MapAccess<'de>,
{
let mut obj = Object::with_capacity(map.size_hint().unwrap_or(0));
while let Some((key, val)) = map.next_entry()? {
obj.insert(key, val);
}
Ok(UniNode::Object(obj))
}
}
impl<'de> de::Deserialize<'de> for UniNode {
fn deserialize<D>(deserializer: D) -> result::Result<UniNode, D::Error>
where
D: de::Deserializer<'de>,
{
deserializer.deserialize_any(UniNodeVisitor)
}
}
#[cfg(test)]
mod tests {
use serde::de::Visitor;
use serde::de::value;
use serde::Deserialize;
use crate::{unode, UniNode};
use super::*;
use std::fmt;
use serde_bytes::ByteBuf;
use crate::serialize::error::UniNodeSerError;
#[test]
fn visit_value() {
let visitor = UniNodeVisitor;
assert_eq!(
visitor.visit_u8::<value::Error>(42).unwrap(),
unode!(42u32)
);
}
#[test]
fn visit_bytes() {
let bytes = UniNode::Bytes(vec![1, 2, 3]);
assert_eq!(
UniNodeVisitor
.visit_bytes::<value::Error>(&[1, 2, 3])
.unwrap(),
bytes
);
assert_eq!(
UniNodeVisitor
.visit_byte_buf::<value::Error>(vec![1, 2, 3])
.unwrap(),
bytes
);
}
#[test]
fn visit_seq() {
type SeqDe =
value::SeqDeserializer<std::vec::IntoIter<u8>, value::Error>;
let seq = SeqDe::new(vec![1, 2, 3].into_iter());
assert_eq!(
UniNodeVisitor.visit_seq(seq).unwrap(),
unode!(1u8, 2u8, 3u8)
);
}
#[test]
fn visit_map() {
type MapDe<'de> = value::MapDeserializer<
'de,
std::vec::IntoIter<(&'de str, u8)>,
value::Error,
>;
let map =
MapDe::new(vec![("one", 1), ("two", 2), ("three", 3)].into_iter());
assert_eq!(
UniNodeVisitor.visit_map(map).unwrap(),
unode!("one" => 1u8, "two" => 2u8, "three" => 3u8)
);
}
pub fn assert_deserialize<T>(node: UniNode, val: T)
where
T: de::DeserializeOwned + fmt::Debug + PartialEq,
{
assert_eq!(T::deserialize(&node).unwrap(), val);
assert_eq!(T::deserialize(node).unwrap(), val);
}
#[test]
fn deserialize_primitive() {
assert_deserialize(unode!(4u8), 4u8);
assert_deserialize(unode!(4u16), 4u16);
assert_deserialize(unode!(4u32), 4u32);
assert_deserialize(unode!(4u64), 4u64);
assert_deserialize(unode!(4i8), 4i8);
assert_deserialize(unode!(4i16), 4i16);
assert_deserialize(unode!(4i32), 4i32);
assert_deserialize(unode!(4i64), 4i64);
assert_deserialize(unode!(4.2f32), 4.2f32);
assert_deserialize(unode!(4.2f64), 4.2f64);
assert_deserialize(unode!(true), true);
assert_deserialize(unode!("a"), 'a');
assert_deserialize(unode!("hello"), "hello".to_string());
let bytes = ByteBuf::from(vec![1u8, 2u8]);
assert_deserialize::<ByteBuf>(unode!(vec![1u8, 2u8]), bytes);
let bytes = ByteBuf::from(vec![104, 101, 108, 108, 111]);
assert_deserialize::<ByteBuf>(unode!("hello"), bytes);
let bytes = ByteBuf::from(vec![1u8, 2u8, 3u8]);
assert_deserialize::<ByteBuf>(unode!(1, 2, 3), bytes);
assert_deserialize(unode!(42), Some(42));
assert_deserialize::<Option<u32>>(unode!(), None);
assert_deserialize::<()>(unode!(), ());
assert_deserialize::<std::marker::PhantomData<u8>>(
unode!(),
std::marker::PhantomData,
);
}
#[test]
fn deserialize_seq() {
let array = UniNode::Bytes(vec![1, 2, 3]);
assert_eq!(Vec::<u32>::deserialize(&array).unwrap(), vec![1, 2, 3]);
assert_eq!(Vec::<u32>::deserialize(array).unwrap(), vec![1, 2, 3]);
let array = unode!(2u32, 3, 4);
assert_eq!(Vec::<u32>::deserialize(&array).unwrap(), vec![2, 3, 4]);
assert_eq!(Vec::<u32>::deserialize(array).unwrap(), vec![2, 3, 4]);
let value = unode!(42u32);
assert_eq!(Vec::<u32>::deserialize(&value).unwrap(), vec![42]);
assert_eq!(Vec::<u32>::deserialize(value).unwrap(), vec![42]);
let array = UniNode::Array(vec![]);
assert_eq!(Vec::<f64>::deserialize(&array).unwrap(), vec![]);
assert_eq!(Vec::<f64>::deserialize(array).unwrap(), vec![]);
}
#[test]
fn deserialize_tuple() {
let tup = ("one".to_string(), 1, 3.18);
assert_deserialize(unode!("one", 1, 3.18), tup);
}
#[test]
fn deserialize_tuple_struct() {
#[derive(Deserialize, PartialEq, Debug)]
struct Rgb(u8, u8, u8);
let tup = Rgb(2, 3, 4);
assert_deserialize(unode!(2u8, 3u8, 4u8), tup);
}
#[test]
fn deserialize_newtype_struct() {
#[derive(Debug, Deserialize, PartialEq)]
struct NewTypeStruct(u8);
assert_deserialize(unode!(2u8), NewTypeStruct(2));
#[derive(Debug, Deserialize, PartialEq)]
enum NewTypeEnum {
V(u8),
}
assert_deserialize(unode!("V" => 4u8), NewTypeEnum::V(4));
}
#[test]
fn deserialize_map() {
#[derive(PartialEq, Eq, Hash, Deserialize, Debug)]
struct Key(u8);
let mut map = std::collections::HashMap::new();
map.insert(Key(1), "One".to_string());
map.insert(Key(2), "Two".to_string());
map.insert(Key(3), "Three".to_string());
assert_deserialize(
unode! {"1" => "One", "2" => "Two", "3" => "Three"},
map,
);
}
#[test]
fn deserialize_struct_test() {
#[derive(Debug, Deserialize, PartialEq)]
struct Point {
x: i32,
y: i32,
}
impl Point {
fn new(x: i32, y: i32) -> Self {
Self { x, y }
}
}
match Point::deserialize(unode!(1i8)).unwrap_err() {
UniNodeSerError::Custom(msg) => assert_eq!(
msg,
String::from(
"invalid type: integer `1`, expected struct Point"
)
),
_ => panic!("Unknown error"),
}
#[derive(Debug, Deserialize, PartialEq)]
struct Test {
int: u32,
float: f64,
text: String,
data: Vec<Point>,
node: UniNode,
bytes: Vec<u8>,
points: Vec<Point>,
}
let data = Test {
int: 42,
float: 3.18,
text: "hello".to_string(),
data: vec![Point::new(1, 2), Point::new(2, 3), Point::new(3, 4)],
node: 10.into(),
bytes: vec![97, 98, 99],
points: vec![Point::new(4, 6)],
};
let node = unode! {
"int" => 42u32,
"float" => 3.18,
"text" => "hello",
"data" => unode![
unode!{"x" => 1, "y" => 2},
unode!{"x" => 2, "y" => 3},
unode!{"x" => 3, "y" => 4},
],
"node" => 10,
"bytes" => vec![97u8, 98u8, 99u8],
"points" => unode!{"x" => 4, "y" => 6},
};
assert_deserialize(node, data);
}
#[test]
fn deserialize_enum() {
use std::ops::Bound;
assert_deserialize(unode!("Unbounded"), Bound::<usize>::Unbounded);
}
#[test]
fn deserialize_tuple_variant() {
#[derive(Deserialize, Debug, PartialEq)]
enum E {
T(u8, u8),
U(String, u32, u32),
}
let tup = E::T(2, 3);
assert_deserialize(unode!("T" => unode![2u8, 3u8]), tup);
}
#[test]
fn deserialize_struct_variant() {
#[derive(Deserialize, PartialEq, Debug)]
enum E {
S { r: u8, g: u8, b: u8 },
}
let data = E::S { r: 3, g: 5, b: 6 };
let node = unode! {
"S" => unode!{"r" => 3u8, "g" => 5u8, "b" => 6u8}
};
assert_deserialize(node, data);
}
}