use std::result;
use serde::ser;
use crate::value::{UniNode, Object, Array};
use super::error::{Result, UniNodeSerError};
pub struct SerializeMap {
map: Object,
next_key: Option<String>,
}
impl ser::SerializeMap for SerializeMap {
type Error = UniNodeSerError;
type Ok = UniNode;
fn serialize_key<T>(&mut self, key: &T) -> Result<()>
where
T: ?Sized + ser::Serialize,
{
let key = key.serialize(UniNodeSerializer)?;
self.next_key = Some(
key.to_string()
.map_err(|_| UniNodeSerError::KeyMustBeAString)?,
);
Ok(())
}
fn serialize_value<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + ser::Serialize,
{
let key = self
.next_key
.take()
.ok_or(UniNodeSerError::KeyMustBeAString)?;
self.map.insert(key, value.serialize(UniNodeSerializer)?);
Ok(())
}
fn end(self) -> Result<Self::Ok> {
Ok(UniNode::Object(self.map))
}
}
impl ser::SerializeStruct for SerializeMap {
type Error = UniNodeSerError;
type Ok = UniNode;
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
where
T: ?Sized + ser::Serialize,
{
ser::SerializeMap::serialize_entry(self, key, value)
}
fn end(self) -> Result<Self::Ok> {
ser::SerializeMap::end(self)
}
}
pub struct SerializeVec {
vec: Array,
}
impl ser::SerializeSeq for SerializeVec {
type Error = UniNodeSerError;
type Ok = UniNode;
fn serialize_element<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + ser::Serialize,
{
self.vec.push(value.serialize(UniNodeSerializer)?);
Ok(())
}
fn end(self) -> Result<Self::Ok> {
Ok(UniNode::Array(self.vec))
}
}
impl ser::SerializeTuple for SerializeVec {
type Error = UniNodeSerError;
type Ok = UniNode;
fn serialize_element<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + ser::Serialize,
{
ser::SerializeSeq::serialize_element(self, value)
}
fn end(self) -> Result<Self::Ok> {
ser::SerializeSeq::end(self)
}
}
impl ser::SerializeTupleStruct for SerializeVec {
type Error = UniNodeSerError;
type Ok = UniNode;
fn serialize_field<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + ser::Serialize,
{
ser::SerializeSeq::serialize_element(self, value)
}
fn end(self) -> Result<Self::Ok> {
ser::SerializeSeq::end(self)
}
}
pub struct SerializeStructVariant {
map: Object,
name: String,
}
impl ser::SerializeStructVariant for SerializeStructVariant {
type Error = UniNodeSerError;
type Ok = UniNode;
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
where
T: ?Sized + ser::Serialize,
{
self.map
.insert(String::from(key), value.serialize(UniNodeSerializer)?);
Ok(())
}
fn end(self) -> Result<Self::Ok> {
let mut tbl = Object::new();
tbl.insert(self.name, UniNode::Object(self.map));
Ok(UniNode::Object(tbl))
}
}
pub struct SerializeTupleVariant {
vec: Array,
name: String,
}
impl ser::SerializeTupleVariant for SerializeTupleVariant {
type Error = UniNodeSerError;
type Ok = UniNode;
fn serialize_field<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + ser::Serialize,
{
self.vec.push(value.serialize(UniNodeSerializer)?);
Ok(())
}
fn end(self) -> Result<Self::Ok> {
let mut tbl = Object::new();
tbl.insert(self.name.to_string(), UniNode::Array(self.vec));
Ok(UniNode::Object(tbl))
}
}
#[derive(Default)]
pub struct UniNodeSerializer;
impl ser::Serializer for UniNodeSerializer {
type Error = UniNodeSerError;
type Ok = UniNode;
type SerializeMap = SerializeMap;
type SerializeSeq = SerializeVec;
type SerializeStruct = SerializeMap;
type SerializeStructVariant = SerializeStructVariant;
type SerializeTuple = SerializeVec;
type SerializeTupleStruct = SerializeVec;
type SerializeTupleVariant = SerializeTupleVariant;
fn serialize_bool(self, value: bool) -> Result<Self::Ok> {
Ok(UniNode::from(value))
}
fn serialize_i8(self, value: i8) -> Result<Self::Ok> {
Ok(UniNode::from(value))
}
fn serialize_i16(self, value: i16) -> Result<Self::Ok> {
Ok(UniNode::from(value))
}
fn serialize_i32(self, value: i32) -> Result<Self::Ok> {
Ok(UniNode::from(value))
}
fn serialize_i64(self, value: i64) -> Result<Self::Ok> {
Ok(UniNode::from(value))
}
fn serialize_u8(self, value: u8) -> Result<Self::Ok> {
Ok(UniNode::from(value))
}
fn serialize_u16(self, value: u16) -> Result<Self::Ok> {
Ok(UniNode::from(value))
}
fn serialize_u32(self, value: u32) -> Result<Self::Ok> {
Ok(UniNode::from(value))
}
fn serialize_u64(self, value: u64) -> Result<Self::Ok> {
Ok(UniNode::from(value))
}
fn serialize_f32(self, value: f32) -> Result<Self::Ok> {
Ok(UniNode::from(value))
}
fn serialize_f64(self, value: f64) -> Result<Self::Ok> {
Ok(UniNode::from(value))
}
fn serialize_char(self, value: char) -> Result<Self::Ok> {
self.serialize_str(&value.to_string())
}
fn serialize_str(self, value: &str) -> Result<Self::Ok> {
Ok(UniNode::from(value))
}
fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok> {
Ok(UniNode::from(value))
}
fn serialize_none(self) -> Result<Self::Ok> {
self.serialize_unit()
}
fn serialize_some<T>(self, value: &T) -> Result<Self::Ok>
where
T: ?Sized + ser::Serialize,
{
value.serialize(self)
}
fn serialize_unit(self) -> Result<Self::Ok> {
Ok(UniNode::Null)
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> {
Ok(UniNode::Null)
}
fn serialize_unit_variant(
self, _name: &'static str, _idx: u32, var: &'static str,
) -> Result<Self::Ok> {
self.serialize_str(var)
}
fn serialize_newtype_struct<T>(
self, _name: &'static str, value: &T,
) -> Result<Self::Ok>
where
T: ?Sized + ser::Serialize,
{
value.serialize(self)
}
fn serialize_newtype_variant<T>(
self, _name: &'static str, _idx: u32, var: &'static str, value: &T,
) -> Result<Self::Ok>
where
T: ?Sized + ser::Serialize,
{
let mut ret = Object::new();
ret.insert(var.to_string(), value.serialize(self)?);
Ok(UniNode::Object(ret))
}
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
Ok(SerializeVec {
vec: Vec::with_capacity(len.unwrap_or(0)),
})
}
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
self.serialize_seq(Some(len))
}
fn serialize_tuple_struct(
self, _name: &'static str, len: usize,
) -> Result<Self::SerializeTupleStruct> {
self.serialize_seq(Some(len))
}
fn serialize_tuple_variant(
self, _name: &'static str, _idx: u32, var: &'static str, len: usize,
) -> Result<Self::SerializeTupleVariant> {
Ok(SerializeTupleVariant {
name: var.to_string(),
vec: Array::with_capacity(len),
})
}
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
Ok(SerializeMap {
map: Object::new(),
next_key: None,
})
}
fn serialize_struct(
self, _name: &'static str, len: usize,
) -> Result<Self::SerializeStruct> {
self.serialize_map(Some(len))
}
fn serialize_struct_variant(
self, _name: &'static str, _idx: u32, var: &'static str, _len: usize,
) -> Result<Self::SerializeStructVariant> {
Ok(SerializeStructVariant {
map: Object::new(),
name: var.to_string(),
})
}
fn collect_str<T: ?Sized>(self, value: &T) -> Result<UniNode>
where
T: std::fmt::Display,
{
Ok(UniNode::String(value.to_string()))
}
}
impl ser::Serialize for UniNode {
fn serialize<S>(&self, serializer: S) -> result::Result<S::Ok, S::Error>
where
S: ser::Serializer,
{
match self {
UniNode::Boolean(v) => serializer.serialize_bool(*v),
UniNode::Integer(v) => serializer.serialize_i64(*v),
UniNode::UInteger(v) => serializer.serialize_u64(*v),
UniNode::Float(v) => serializer.serialize_f64(*v),
UniNode::Bytes(v) => serializer.serialize_bytes(v),
UniNode::String(v) => serializer.serialize_str(v),
UniNode::Null => serializer.serialize_unit(),
UniNode::Array(v) => v.serialize(serializer),
UniNode::Object(v) => {
use serde::ser::SerializeMap;
let mut map = serializer.serialize_map(Some(v.len()))?;
for (k, v) in v {
map.serialize_entry(k, v)?;
}
map.end()
},
}
}
}
pub fn serialize<T>(value: &T) -> Result<UniNode>
where
T: serde::Serialize,
{
value.serialize(UniNodeSerializer)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::unode;
use serde::Serialize;
use serde_bytes::Bytes;
#[test]
fn serialize_node() {
let unode = unode! {"one" => 1, "two" => 2, "arr" => unode![1, 2, 3]};
assert_eq!(serialize(&unode).unwrap(), unode);
#[derive(Debug, Serialize)]
struct Test {
val1: UniNode,
val2: UniNode,
}
let data = Test {
val1: unode.clone(),
val2: unode!(1),
};
assert_eq!(
serialize(&data).unwrap(),
unode! {"val1" => unode, "val2" => 1}
);
}
#[test]
fn serialize_primitives() {
use std::ops::RangeBounds;
assert_eq!(serialize(&true).unwrap(), unode!(true));
assert_eq!(serialize(&4u8).unwrap(), unode!(4u8));
assert_eq!(serialize(&4u16).unwrap(), unode!(4u16));
assert_eq!(serialize(&4u32).unwrap(), unode!(4u32));
assert_eq!(serialize(&4u64).unwrap(), unode!(4u64));
assert_eq!(serialize(&4i8).unwrap(), unode!(4i8));
assert_eq!(serialize(&4i16).unwrap(), unode!(4i16));
assert_eq!(serialize(&4i32).unwrap(), unode!(4i32));
assert_eq!(serialize(&4i64).unwrap(), unode!(4i64));
assert_eq!(serialize(&4.2f32).unwrap(), unode!(4.2f32));
assert_eq!(serialize(&43.3f64).unwrap(), unode!(43.3f64));
assert_eq!(serialize(&'a').unwrap(), unode!("a"));
assert_eq!(serialize(&"hello").unwrap(), unode!("hello"));
assert_eq!(serialize(&Option::<u8>::None).unwrap(), unode!());
assert_eq!(serialize(&Some(12)).unwrap(), unode!(12));
let bytes = Bytes::new(b"abc");
assert_eq!(serialize(&bytes).unwrap(), unode!(vec![97u8, 98u8, 99u8]));
assert_eq!(serialize(&()).unwrap(), unode!());
assert_eq!(
serialize(&std::marker::PhantomData::<u8>).unwrap(),
unode!()
);
assert_eq!(
serialize(&(..100).start_bound()).unwrap(),
unode!("Unbounded")
);
}
#[test]
fn serialize_newtype() {
#[derive(Debug, Serialize)]
struct NewTypeStruct(u8);
assert_eq!(serialize(&NewTypeStruct(2)).unwrap(), unode!(2u8));
#[derive(Debug, Serialize)]
enum NewTypeEnum {
V(u8),
}
assert_eq!(serialize(&NewTypeEnum::V(4)).unwrap(), unode!("V" => 4u8));
}
#[test]
fn serialize_seq() {
let arr = vec!["one", "two", "three"];
assert_eq!(serialize(&arr).unwrap(), unode!("one", "two", "three"));
}
#[test]
fn serialize_tuple() {
let tup = ("one", 1, 3.18);
assert_eq!(serialize(&tup).unwrap(), unode!("one", 1, 3.18));
}
#[test]
fn serialize_tuple_struct() {
#[derive(Serialize)]
struct Rgb(u8, u8, u8);
let tup = Rgb(2, 3, 4);
assert_eq!(serialize(&tup).unwrap(), unode!(2u8, 3u8, 4u8));
}
#[test]
fn serialize_tuple_variant() {
#[derive(Serialize)]
enum E {
T(u8, u8),
}
let tup = E::T(2, 3);
assert_eq!(serialize(&tup).unwrap(), unode!("T" => unode![2u8, 3u8]));
}
#[test]
fn serialize_struct() {
#[derive(Debug, Serialize)]
struct Point {
x: i32,
y: i32,
}
impl Point {
fn new(x: i32, y: i32) -> Self {
Self { x, y }
}
}
#[derive(Debug, Serialize)]
struct Test<'a> {
int: u32,
float: f64,
text: String,
data: Vec<Point>,
node: UniNode,
bytes: &'a Bytes,
}
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: Bytes::new(b"abc"),
};
assert_eq!(
serialize(&data).unwrap(),
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],
}
);
}
#[test]
fn serialize_map() {
use std::collections::HashMap;
#[derive(PartialEq, Eq, Hash, Serialize)]
struct Key(u8);
let mut map = HashMap::new();
map.insert(Key(1), "One");
map.insert(Key(2), "Two");
map.insert(Key(3), "Three");
assert_eq!(
serialize(&map).unwrap(),
unode! {"1" => "One", "2" => "Two", "3" => "Three"}
);
}
#[test]
fn serialize_struct_variant() {
#[derive(Serialize)]
enum E {
S { r: u8, g: u8, b: u8 },
}
let data = E::S { r: 3, g: 5, b: 6 };
assert_eq!(
serialize(&data).unwrap(),
unode! {
"S" => unode!{"r" => 3u8, "g" => 5u8, "b" => 6u8}
}
);
}
#[test]
fn serialize_bytes() {
use serde::{Serialize, Deserialize, de::DeserializeOwned};
use std::fmt::Debug;
fn test_owned_data<T>(data: T)
where
T: Serialize + DeserializeOwned + Debug + PartialEq,
{
let node = serialize(&data).unwrap();
assert_eq!(T::deserialize(&node).unwrap(), data);
assert_eq!(T::deserialize(node).unwrap(), data);
}
test_owned_data(vec![1, 2, 3]);
test_owned_data(String::from("hello"));
let data = "abc";
let node = serialize(&data).unwrap();
assert_eq!(<&str>::deserialize(&node).unwrap(), data);
let data = Bytes::new(b"abc");
let node = serialize(&data).unwrap();
assert_eq!(<&Bytes>::deserialize(&node).unwrap(), data);
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Data<'a> {
#[serde(with = "serde_bytes")]
data_slice: &'a [u8],
#[serde(with = "serde_bytes")]
data_buf: Vec<u8>,
}
let data = Data {
data_slice: b"abc",
data_buf: vec![1, 2, 3],
};
let node = serialize(&data).unwrap();
assert_eq!(Data::deserialize(&node).unwrap(), data);
}
}