use serde::{
ser::{self, SerializeTuple},
Serialize
};
use paste::paste;
use crate::error::{Error, Result};
pub struct Serializer {
stack: Vec<Vec<u8>>
}
impl Serializer {
pub fn to_bytes<T>(value: &T) -> Result<Vec<u8>>
where
T: Serialize,
{
let mut serializer = Serializer {
stack: Vec::new()
};
serializer.stack.push(Vec::new());
value.serialize(&mut serializer)?;
Ok(serializer.stack.pop().unwrap())
}
}
fn be_bytes_compact(src: &[u8]) -> &[u8] {
for i in 0..src.len() {
if src[i] != 0 { return &src[i..] }
}
return &[]
}
macro_rules! impl_seralize_integer {
($($ity:ident),+) => {
paste! {$(
fn [<serialize_ $ity>](self, v: $ity) -> Result<()> {
self.serialize_bytes(be_bytes_compact(&v.to_be_bytes()))
}
)+}
}
}
macro_rules! impl_seralize_not_supported {
($($ity:ident),+) => {
paste! {$(
fn [<serialize_ $ity>](self, _v: $ity) -> Result<()> {
Err(Error::TypeNotSupported)
}
)+}
}
}
impl<'a> ser::Serializer for &'a mut Serializer {
type Ok = ();
type Error = Error;
type SerializeSeq = Self;
type SerializeTuple = Self;
type SerializeTupleStruct = Self;
type SerializeTupleVariant = Self;
type SerializeMap = Self;
type SerializeStruct = Self;
type SerializeStructVariant = Self;
impl_seralize_not_supported! {bool, f32, f64, i8, i16, i32, i64}
impl_seralize_integer! {u8, u16, u32, u64}
fn serialize_char(self, v: char) -> Result<()> {
self.serialize_str(&v.to_string())
}
fn serialize_str(self, v: &str) -> Result<()> {
self.serialize_bytes(v.as_bytes())
}
fn serialize_bytes(self, v: &[u8]) -> Result<()> {
let last = self.stack.last_mut().unwrap();
match v.len() as u64 {
1 if v[0] < 128 => last.extend(v),
0..=55 => {
last.push(128 + v.len() as u8);
last.extend(v);
},
56..=u64::MAX => {
let be_bytes = v.len().to_be_bytes();
let len_be = be_bytes_compact(&be_bytes);
last.push(183 + len_be.len() as u8);
last.extend(len_be);
last.extend(v);
}
}
Ok(())
}
fn serialize_none(self) -> Result<()> {
let last = self.stack.last_mut().unwrap();
last.push(0x80);
Ok(())
}
fn serialize_some<T>(self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
value.serialize(self)
}
fn serialize_unit(self) -> Result<()> {
let unit = self.serialize_tuple(0)?;
unit.end()
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
self.serialize_none()
}
fn serialize_unit_variant(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
) -> Result<()> {
self.serialize_none()
}
fn serialize_newtype_struct<T>(
self,
_name: &'static str,
value: &T,
) -> Result<()>
where
T: ?Sized + Serialize,
{
value.serialize(self)
}
fn serialize_newtype_variant<T>(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
value: &T,
) -> Result<()>
where
T: ?Sized + Serialize,
{
value.serialize(self)
}
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
self.stack.push(Vec::new());
Ok(self)
}
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
self.stack.push(Vec::new());
Ok(self)
}
fn serialize_tuple_struct(
self,
_name: &'static str,
len: usize,
) -> Result<Self::SerializeTupleStruct> {
self.serialize_tuple(len)
}
fn serialize_tuple_variant(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
len: usize,
) -> Result<Self::SerializeTupleVariant> {
self.serialize_tuple(len)
}
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
self.stack.push(Vec::new());
Ok(self)
}
fn serialize_struct(
self,
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeStruct> {
self.stack.push(Vec::new());
Ok(self)
}
fn serialize_struct_variant(
self,
name: &'static str,
_variant_index: u32,
_variant: &'static str,
len: usize,
) -> Result<Self::SerializeStructVariant> {
self.serialize_struct(name, len)
}
}
impl<'a> ser::SerializeSeq for &'a mut Serializer {
type Ok = ();
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<()> {
self.frame_return();
Ok(())
}
}
impl<'a> ser::SerializeTuple for &'a mut Serializer {
type Ok = ();
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<()> {
self.frame_return();
Ok(())
}
}
impl<'a> ser::SerializeTupleStruct for &'a mut Serializer {
type Ok = ();
type Error = Error;
fn serialize_field<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<()> {
self.frame_return();
Ok(())
}
}
impl<'a> ser::SerializeTupleVariant for &'a mut Serializer {
type Ok = ();
type Error = Error;
fn serialize_field<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<()> {
self.frame_return();
Ok(())
}
}
impl<'a> ser::SerializeMap for &'a mut Serializer {
type Ok = ();
type Error = Error;
fn serialize_key<T>(&mut self, _key: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
Ok(())
}
fn serialize_value<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<()> {
self.frame_return();
Ok(())
}
}
impl<'a> ser::SerializeStruct for &'a mut Serializer {
type Ok = ();
type Error = Error;
fn serialize_field<T>(&mut self, _key: &'static str, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<()> {
self.frame_return();
Ok(())
}
}
impl Serializer {
fn frame_return(&mut self) {
let frame = self.stack.pop().unwrap();
let len = frame.len();
let last = self.stack.last_mut().unwrap();
match len as u64 {
0..=55 => {
last.push(192 + len as u8);
last.extend(frame);
},
56..=u64::MAX => {
let be_bytes = len.to_be_bytes();
let len_be = be_bytes_compact(&be_bytes);
last.push(247 + len_be.len() as u8);
last.extend(len_be);
last.extend(frame);
}
}
}
}
impl<'a> ser::SerializeStructVariant for &'a mut Serializer {
type Ok = ();
type Error = Error;
fn serialize_field<T>(&mut self, _key: &'static str, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<()> {
self.frame_return();
Ok(())
}
}