nettext/src/serde/ser.rs
2022-11-18 18:00:30 +01:00

458 lines
11 KiB
Rust

use serde::{ser, Serialize};
use crate::enc::*;
use crate::serde::error::{Error, Result};
use serde::ser::Error as SerError;
pub struct Serializer;
pub fn to_term<T>(value: &T) -> Result<Term<'static>>
where
T: Serialize,
{
value.serialize(&mut Serializer)
}
pub fn to_bytes<T>(value: &T) -> Result<Vec<u8>>
where
T: Serialize,
{
Ok(value.serialize(&mut Serializer)?.encode())
}
impl<'a> ser::Serializer for &'a mut Serializer {
type Ok = Term<'static>;
type Error = Error;
type SerializeSeq = SeqSerializer;
type SerializeTuple = SeqSerializer;
type SerializeTupleStruct = SeqSerializer;
type SerializeTupleVariant = SeqSerializer;
type SerializeMap = MapSerializer;
type SerializeStruct = StructSerializer;
type SerializeStructVariant = StructVariantSerializer;
fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
Ok(if v {
safe_raw(b"true")
} else {
safe_raw(b"false")
})
}
fn serialize_i8(self, v: i8) -> Result<Self::Ok> {
self.serialize_i64(i64::from(v))
}
fn serialize_i16(self, v: i16) -> Result<Self::Ok> {
self.serialize_i64(i64::from(v))
}
fn serialize_i32(self, v: i32) -> Result<Self::Ok> {
self.serialize_i64(i64::from(v))
}
fn serialize_i64(self, v: i64) -> Result<Self::Ok> {
Ok(safe_raw_owned(v.to_string().into_bytes()))
}
fn serialize_u8(self, v: u8) -> Result<Self::Ok> {
self.serialize_u64(u64::from(v))
}
fn serialize_u16(self, v: u16) -> Result<Self::Ok> {
self.serialize_u64(u64::from(v))
}
fn serialize_u32(self, v: u32) -> Result<Self::Ok> {
self.serialize_u64(u64::from(v))
}
fn serialize_u64(self, v: u64) -> Result<Self::Ok> {
Ok(safe_raw_owned(v.to_string().into_bytes()))
}
fn serialize_f32(self, v: f32) -> Result<Self::Ok> {
self.serialize_f64(f64::from(v))
}
fn serialize_f64(self, v: f64) -> Result<Self::Ok> {
Ok(string_owned(v.to_string())?)
}
fn serialize_char(self, v: char) -> Result<Self::Ok> {
self.serialize_str(&v.to_string())
}
fn serialize_str(self, v: &str) -> Result<Self::Ok> {
Ok(bytes(v.as_bytes()))
}
fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok> {
Ok(bytes(v))
}
fn serialize_none(self) -> Result<Self::Ok> {
Ok(dict([]))
}
fn serialize_some<T>(self, value: &T) -> Result<Self::Ok>
where
T: ?Sized + Serialize,
{
Ok(value.serialize(self)?.nested())
}
fn serialize_unit(self) -> Result<Self::Ok> {
Ok(dict([]))
}
fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok> {
Ok(string(name)?)
}
fn serialize_unit_variant(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<Self::Ok> {
Ok(string_owned(format!("{}.{}", name, variant))?)
}
fn serialize_newtype_struct<T>(self, name: &'static str, value: &T) -> Result<Self::Ok>
where
T: ?Sized + Serialize,
{
Ok(list_flatten([string(name)?, value.serialize(self)?])?)
}
fn serialize_newtype_variant<T>(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
value: &T,
) -> Result<Self::Ok>
where
T: ?Sized + Serialize,
{
Ok(list_flatten([
string_owned(format!("{}.{}", name, variant))?,
value.serialize(self)?,
])?)
}
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
Ok(SeqSerializer { items: vec![] })
}
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
Ok(SeqSerializer {
items: Vec::with_capacity(len),
})
}
fn serialize_tuple_struct(
self,
name: &'static str,
len: usize,
) -> Result<Self::SerializeTupleStruct> {
let mut items = Vec::with_capacity(len + 1);
items.push(string(name)?);
Ok(SeqSerializer { items })
}
fn serialize_tuple_variant(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeTupleVariant> {
let mut items = Vec::with_capacity(len + 1);
items.push(string_owned(format!("{}.{}", name, variant))?);
Ok(SeqSerializer { items })
}
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
Ok(MapSerializer {
next: None,
fields: vec![],
})
}
fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
Ok(StructSerializer {
name,
fields: Vec::with_capacity(len),
})
}
fn serialize_struct_variant(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeStructVariant> {
Ok(StructVariantSerializer {
name,
variant,
fields: Vec::with_capacity(len),
})
}
}
// -- sub-serializers --
pub struct SeqSerializer {
items: Vec<Term<'static>>,
}
impl ser::SerializeSeq for SeqSerializer {
type Ok = Term<'static>;
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
self.items.push(value.serialize(&mut Serializer)?);
Ok(())
}
fn end(self) -> Result<Self::Ok> {
Ok(list_nested(self.items.into_iter())?)
}
}
impl ser::SerializeTuple for SeqSerializer {
type Ok = Term<'static>;
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
self.items.push(value.serialize(&mut Serializer)?);
Ok(())
}
fn end(self) -> Result<Self::Ok> {
Ok(list_nested(self.items.into_iter())?)
}
}
impl ser::SerializeTupleStruct for SeqSerializer {
type Ok = Term<'static>;
type Error = Error;
fn serialize_field<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
self.items.push(value.serialize(&mut Serializer)?);
Ok(())
}
fn end(self) -> Result<Self::Ok> {
Ok(list_nested(self.items.into_iter())?)
}
}
impl ser::SerializeTupleVariant for SeqSerializer {
type Ok = Term<'static>;
type Error = Error;
fn serialize_field<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
self.items.push(value.serialize(&mut Serializer)?);
Ok(())
}
fn end(self) -> Result<Self::Ok> {
Ok(list_nested(self.items.into_iter())?)
}
}
pub struct MapSerializer {
next: Option<Vec<u8>>,
fields: Vec<(Vec<u8>, Term<'static>)>,
}
impl ser::SerializeMap for MapSerializer {
type Ok = Term<'static>;
type Error = Error;
fn serialize_key<T>(&mut self, key: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
self.next = Some(key.serialize(&mut Serializer)?.encode());
Ok(())
}
fn serialize_value<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
self.fields.push((
self.next
.take()
.ok_or_else(|| Self::Error::custom("no key"))?,
value.serialize(&mut Serializer)?,
));
Ok(())
}
fn end(self) -> Result<Term<'static>> {
Ok(dict_owned_u8(self.fields.into_iter()))
}
}
pub struct StructSerializer {
name: &'static str,
fields: Vec<(&'static str, Term<'static>)>,
}
impl ser::SerializeStruct for StructSerializer {
type Ok = Term<'static>;
type Error = Error;
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
self.fields.push((key, value.serialize(&mut Serializer)?));
Ok(())
}
fn end(self) -> Result<Term<'static>> {
Ok(list([string(self.name)?, dict(self.fields.into_iter())])?)
}
}
pub struct StructVariantSerializer {
name: &'static str,
variant: &'static str,
fields: Vec<(&'static str, Term<'static>)>,
}
impl ser::SerializeStructVariant for StructVariantSerializer {
type Ok = Term<'static>;
type Error = Error;
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
self.fields.push((key, value.serialize(&mut Serializer)?));
Ok(())
}
fn end(self) -> Result<Term<'static>> {
Ok(list([
string_owned(format!("{}.{}", self.name, self.variant))?,
dict(self.fields.into_iter()),
])?)
}
}
// ----
#[cfg(test)]
mod tests {
use super::*;
use serde::Serialize;
use std::collections::HashMap;
#[test]
fn test_struct() {
#[derive(Serialize)]
struct Test {
int: u32,
seq: Vec<&'static str>,
}
let test = Test {
int: 1,
seq: vec!["a", "b"],
};
let expected = br#"Test {
int = 1,
seq = YQ Yg,
}"#;
assert_eq!(&to_bytes(&test).unwrap(), expected);
}
#[test]
fn test_enum() {
#[derive(Serialize)]
enum E {
Unit,
Newtype(u32),
Tuple(u32, u32),
Struct { a: u32 },
}
let u = E::Unit;
let expected = br#"E.Unit"#;
assert_eq!(&to_bytes(&u).unwrap(), expected);
let n = E::Newtype(1);
let expected = br#"E.Newtype 1"#;
assert_eq!(&to_bytes(&n).unwrap(), expected);
let t = E::Tuple(1, 2);
let expected = br#"E.Tuple 1 2"#;
assert_eq!(&to_bytes(&t).unwrap(), expected);
let s = E::Struct { a: 1 };
let expected = br#"E.Struct { a = 1 }"#;
assert_eq!(&to_bytes(&s).unwrap(), expected);
}
#[test]
fn test_seq() {
let u = (1, 2, 3, 4);
let expected = br#"1 2 3 4"#;
assert_eq!(&to_bytes(&u).unwrap(), expected);
let n = (1, 2, (2, 3, 4), 5, 6);
let expected = br#"1 2 { . = 2 3 4 } 5 6"#;
assert_eq!(&to_bytes(&n).unwrap(), expected);
let t = [1, 2, 3, 4];
let expected = br#"1 2 3 4"#;
assert_eq!(&to_bytes(&t).unwrap(), expected);
let s = [[1, 2], [2, 3], [3, 4]];
let expected = br#"{ . = 1 2 } { . = 2 3 } { . = 3 4 }"#;
assert_eq!(&to_bytes(&s).unwrap(), expected);
}
#[test]
fn test_dict() {
let mut d = HashMap::new();
d.insert("hello", "world");
d.insert("dont", "panic");
let expected = br#"{
ZG9udA = cGFuaWM,
aGVsbG8 = d29ybGQ,
}"#;
assert_eq!(&to_bytes(&d).unwrap(), expected);
let mut d = HashMap::new();
d.insert(12, vec![42, 125]);
d.insert(33, vec![19, 22, 21]);
let expected = br#"{
12 = 42 125,
33 = 19 22 21,
}"#;
assert_eq!(&to_bytes(&d).unwrap(), expected);
}
}