2022-11-18 13:15:30 +00:00
|
|
|
use serde::{ser, Serialize};
|
|
|
|
|
|
|
|
use crate::enc::*;
|
|
|
|
use crate::serde::error::{Error, Result};
|
|
|
|
use serde::ser::Error as SerError;
|
|
|
|
|
|
|
|
pub struct Serializer;
|
|
|
|
|
2022-11-18 15:26:44 +00:00
|
|
|
pub fn to_term<T>(value: &T) -> Result<Term<'static>>
|
|
|
|
where
|
|
|
|
T: Serialize,
|
|
|
|
{
|
2022-11-18 15:29:18 +00:00
|
|
|
value.serialize(&mut Serializer)
|
2022-11-18 15:26:44 +00:00
|
|
|
}
|
|
|
|
|
2022-11-18 13:15:30 +00:00
|
|
|
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,
|
|
|
|
{
|
2022-11-18 15:26:44 +00:00
|
|
|
Ok(value.serialize(self)?.nested())
|
2022-11-18 13:15:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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> {
|
2022-11-18 15:26:44 +00:00
|
|
|
Ok(SeqSerializer {
|
|
|
|
items: Vec::with_capacity(len),
|
|
|
|
})
|
2022-11-18 13:15:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn serialize_tuple_struct(
|
|
|
|
self,
|
|
|
|
name: &'static str,
|
|
|
|
len: usize,
|
|
|
|
) -> Result<Self::SerializeTupleStruct> {
|
2022-11-18 15:26:44 +00:00
|
|
|
let mut items = Vec::with_capacity(len + 1);
|
|
|
|
items.push(string(name)?);
|
|
|
|
Ok(SeqSerializer { items })
|
2022-11-18 13:15:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn serialize_tuple_variant(
|
|
|
|
self,
|
|
|
|
name: &'static str,
|
|
|
|
_variant_index: u32,
|
|
|
|
variant: &'static str,
|
|
|
|
len: usize,
|
|
|
|
) -> Result<Self::SerializeTupleVariant> {
|
2022-11-18 15:26:44 +00:00
|
|
|
let mut items = Vec::with_capacity(len + 1);
|
|
|
|
items.push(string_owned(format!("{}.{}", name, variant))?);
|
|
|
|
Ok(SeqSerializer { items })
|
2022-11-18 13:15:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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>>,
|
|
|
|
}
|
2022-11-18 15:29:18 +00:00
|
|
|
impl ser::SerializeSeq for SeqSerializer {
|
2022-11-18 13:15:30 +00:00
|
|
|
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())?)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-18 15:29:18 +00:00
|
|
|
impl ser::SerializeTuple for SeqSerializer {
|
2022-11-18 13:15:30 +00:00
|
|
|
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())?)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-18 15:29:18 +00:00
|
|
|
impl ser::SerializeTupleStruct for SeqSerializer {
|
2022-11-18 13:15:30 +00:00
|
|
|
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())?)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-18 15:29:18 +00:00
|
|
|
impl ser::SerializeTupleVariant for SeqSerializer {
|
2022-11-18 13:15:30 +00:00
|
|
|
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>)>,
|
|
|
|
}
|
|
|
|
|
2022-11-18 15:29:18 +00:00
|
|
|
impl ser::SerializeMap for MapSerializer {
|
2022-11-18 13:15:30 +00:00
|
|
|
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((
|
2022-11-18 15:29:18 +00:00
|
|
|
self.next
|
|
|
|
.take()
|
|
|
|
.ok_or_else(|| Self::Error::custom("no key"))?,
|
2022-11-18 13:15:30 +00:00
|
|
|
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>)>,
|
|
|
|
}
|
|
|
|
|
2022-11-18 15:29:18 +00:00
|
|
|
impl ser::SerializeStructVariant for StructVariantSerializer {
|
2022-11-18 13:15:30 +00:00
|
|
|
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()),
|
|
|
|
])?)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-18 16:57:21 +00:00
|
|
|
// ----
|
2022-11-18 13:15:30 +00:00
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
|
|
|
use serde::Serialize;
|
2022-11-18 15:26:44 +00:00
|
|
|
use std::collections::HashMap;
|
2022-11-18 13:15:30 +00:00
|
|
|
|
|
|
|
#[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();
|
2022-11-18 15:26:44 +00:00
|
|
|
d.insert("hello", "world");
|
|
|
|
d.insert("dont", "panic");
|
2022-11-18 13:15:30 +00:00
|
|
|
let expected = br#"{
|
|
|
|
ZG9udA = cGFuaWM,
|
|
|
|
aGVsbG8 = d29ybGQ,
|
|
|
|
}"#;
|
|
|
|
assert_eq!(&to_bytes(&d).unwrap(), expected);
|
|
|
|
|
|
|
|
let mut d = HashMap::new();
|
2022-11-18 15:26:44 +00:00
|
|
|
d.insert(12, vec![42, 125]);
|
|
|
|
d.insert(33, vec![19, 22, 21]);
|
2022-11-18 13:15:30 +00:00
|
|
|
let expected = br#"{
|
|
|
|
12 = 42 125,
|
|
|
|
33 = 19 22 21,
|
|
|
|
}"#;
|
|
|
|
assert_eq!(&to_bytes(&d).unwrap(), expected);
|
|
|
|
}
|
|
|
|
}
|