use crate::{constants::*, Error, Result};
use serde::{ser, Serialize};
use std::{convert::TryFrom, io::Write};
pub fn to_vec<T>(value: &T) -> Result<Vec<u8>>
where
T: ?Sized + Serialize,
{
let mut writer = Vec::new();
to_writer(&mut writer, value)?;
Ok(writer)
}
pub fn to_writer<W, T>(writer: W, value: &T) -> Result<()>
where
W: Write,
T: ?Sized + Serialize,
{
let mut ser = Serializer::new(writer);
value.serialize(&mut ser)
}
pub struct Serializer<W>
where
W: Write,
{
writer: W,
}
impl<W> Serializer<W>
where
W: Write,
{
pub fn new(writer: W) -> Self {
Self { writer }
}
pub fn into_inner(self) -> W {
self.writer
}
}
impl<'a, W> ser::Serializer for &'a mut Serializer<W>
where
W: Write,
{
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;
fn serialize_bool(self, value: bool) -> Result<()> {
Ok(self.writer.write_all(&[TYPE_BOOLEAN | value as u8])?)
}
fn serialize_i8(self, value: i8) -> Result<()> {
self.serialize_i64(value as i64)
}
fn serialize_i16(self, value: i16) -> Result<()> {
self.serialize_i64(value as i64)
}
fn serialize_i32(self, value: i32) -> Result<()> {
self.serialize_i64(value as i64)
}
fn serialize_i64(self, value: i64) -> Result<()> {
write_integer(&mut self.writer, TYPE_INTEGER, value)
}
fn serialize_u8(self, value: u8) -> Result<()> {
self.serialize_i64(value as i64)
}
fn serialize_u16(self, value: u16) -> Result<()> {
self.serialize_i64(value as i64)
}
fn serialize_u32(self, value: u32) -> Result<()> {
self.serialize_i64(value as i64)
}
fn serialize_u64(self, value: u64) -> Result<()> {
self.serialize_i64(i64::try_from(value)?)
}
fn serialize_f32(self, value: f32) -> Result<()> {
self.serialize_f64(value as f64)
}
fn serialize_f64(self, value: f64) -> Result<()> {
self.writer.write_all(&[TYPE_FLOAT | 8])?;
Ok(self.writer.write_all(&value.to_be_bytes())?)
}
fn serialize_char(self, value: char) -> Result<()> {
self.serialize_i64(value as i64)
}
fn serialize_str(self, value: &str) -> Result<()> {
write_integer(&mut self.writer, TYPE_STRING, value.len() as i64)?;
Ok(self.writer.write_all(value.as_bytes())?)
}
fn serialize_bytes(self, value: &[u8]) -> Result<()> {
write_integer(&mut self.writer, TYPE_RAW, value.len() as i64)?;
Ok(self.writer.write_all(value)?)
}
fn serialize_unit(self) -> Result<()> {
Ok(self.writer.write_all(&[TYPE_NULL])?)
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
self.serialize_unit()
}
fn serialize_unit_variant(
self,
_name: &'static str,
variant_index: u32,
_variant: &'static str,
) -> Result<()> {
self.serialize_u32(variant_index)
}
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,
{
use ser::SerializeSeq;
let mut seq = self.serialize_seq(Some(2))?;
seq.serialize_element(&variant_index)?;
seq.serialize_element(value)?;
seq.end()
}
fn serialize_none(self) -> Result<()> {
self.serialize_unit()
}
fn serialize_some<T>(self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
value.serialize(self)
}
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
self.writer.write_all(&[TYPE_LIST])?;
Ok(self)
}
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_tuple(len)
}
fn serialize_tuple_variant(
self,
_name: &'static str,
variant_index: u32,
_variant: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleVariant> {
use ser::SerializeSeq;
let mut seq = self.serialize_seq(None)?;
seq.serialize_element(&variant_index)?;
Ok(seq)
}
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
self.writer.write_all(&[TYPE_DICTIONARY])?;
Ok(self)
}
fn serialize_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
self.serialize_tuple(len)
}
fn serialize_struct_variant(
self,
name: &'static str,
variant_index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeStructVariant> {
self.serialize_tuple_variant(name, variant_index, variant, len)
}
}
impl<'a, W> ser::SerializeSeq for &'a mut Serializer<W>
where
W: Write,
{
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<()> {
Ok(self.writer.write_all(&[TYPE_END])?)
}
}
impl<'a, W> ser::SerializeTuple for &'a mut Serializer<W>
where
W: Write,
{
type Ok = ();
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
ser::SerializeSeq::serialize_element(self, value)
}
fn end(self) -> Result<()> {
ser::SerializeSeq::end(self)
}
}
impl<'a, W> ser::SerializeTupleStruct for &'a mut Serializer<W>
where
W: Write,
{
type Ok = ();
type Error = Error;
fn serialize_field<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
ser::SerializeSeq::serialize_element(self, value)
}
fn end(self) -> Result<()> {
ser::SerializeSeq::end(self)
}
}
impl<'a, W> ser::SerializeTupleVariant for &'a mut Serializer<W>
where
W: Write,
{
type Ok = ();
type Error = Error;
fn serialize_field<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
ser::SerializeSeq::serialize_element(self, value)
}
fn end(self) -> Result<()> {
ser::SerializeSeq::end(self)
}
}
impl<'a, W> ser::SerializeMap for &'a mut Serializer<W>
where
W: Write,
{
type Ok = ();
type Error = Error;
fn serialize_key<T>(&mut self, key: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
key.serialize(KeySerializer(&mut **self))
}
fn serialize_value<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<()> {
Ok(self.writer.write_all(&[TYPE_END])?)
}
}
impl<'a, W> ser::SerializeStruct for &'a mut Serializer<W>
where
W: Write,
{
type Ok = ();
type Error = Error;
fn serialize_field<T>(&mut self, _name: &'static str, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
ser::SerializeSeq::serialize_element(self, value)
}
fn end(self) -> Result<()> {
ser::SerializeSeq::end(self)
}
}
impl<'a, W> ser::SerializeStructVariant for &'a mut Serializer<W>
where
W: Write,
{
type Ok = ();
type Error = Error;
fn serialize_field<T>(&mut self, name: &'static str, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
ser::SerializeStruct::serialize_field(self, name, value)
}
fn end(self) -> Result<()> {
ser::SerializeSeq::end(self)
}
}
fn write_integer<W>(writer: &mut W, typ: u8, value: i64) -> Result<()>
where
W: Write,
{
let len = if value >= i8::MIN as i64 && value <= i8::MAX as i64 {
1
} else if value >= i16::MIN as i64 && value <= i16::MAX as i64 {
2
} else if value >= i32::MIN as i64 && value <= i32::MAX as i64 {
4
} else {
8
};
writer.write_all(&[typ | len as u8])?;
let start = 8 - len as usize;
let mut buf = [0u8; 8];
buf[..len].copy_from_slice(&value.to_be_bytes()[start..]);
Ok(writer.write_all(&buf[..len])?)
}
struct KeySerializer<'a, W>(&'a mut Serializer<W>)
where
W: Write;
impl<'a, W> ser::Serializer for KeySerializer<'a, W>
where
W: Write,
{
type Ok = ();
type Error = Error;
type SerializeSeq = ser::Impossible<(), Error>;
type SerializeTuple = ser::Impossible<(), Error>;
type SerializeTupleStruct = ser::Impossible<(), Error>;
type SerializeTupleVariant = ser::Impossible<(), Error>;
type SerializeMap = ser::Impossible<(), Error>;
type SerializeStruct = ser::Impossible<(), Error>;
type SerializeStructVariant = ser::Impossible<(), Error>;
fn serialize_bool(self, _value: bool) -> Result<()> {
Err(Error::WrongType)
}
fn serialize_i8(self, _value: i8) -> Result<()> {
Err(Error::WrongType)
}
fn serialize_i16(self, _value: i16) -> Result<()> {
Err(Error::WrongType)
}
fn serialize_i32(self, _value: i32) -> Result<()> {
Err(Error::WrongType)
}
fn serialize_i64(self, _value: i64) -> Result<()> {
Err(Error::WrongType)
}
fn serialize_u8(self, _value: u8) -> Result<()> {
Err(Error::WrongType)
}
fn serialize_u16(self, _value: u16) -> Result<()> {
Err(Error::WrongType)
}
fn serialize_u32(self, _value: u32) -> Result<()> {
Err(Error::WrongType)
}
fn serialize_u64(self, _value: u64) -> Result<()> {
Err(Error::WrongType)
}
fn serialize_f32(self, _value: f32) -> Result<()> {
Err(Error::WrongType)
}
fn serialize_f64(self, _value: f64) -> Result<()> {
Err(Error::WrongType)
}
fn serialize_char(self, _value: char) -> Result<()> {
Err(Error::WrongType)
}
fn serialize_str(self, value: &str) -> Result<()> {
self.0.serialize_str(value)
}
fn serialize_bytes(self, _value: &[u8]) -> Result<()> {
Err(Error::WrongType)
}
fn serialize_unit(self) -> Result<()> {
Err(Error::WrongType)
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
Err(Error::WrongType)
}
fn serialize_unit_variant(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
) -> Result<()> {
Err(Error::WrongType)
}
fn serialize_newtype_struct<T>(self, _name: &'static str, _value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
Err(Error::WrongType)
}
fn serialize_newtype_variant<T>(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_value: &T,
) -> Result<()>
where
T: ?Sized + Serialize,
{
Err(Error::WrongType)
}
fn serialize_none(self) -> Result<()> {
Err(Error::WrongType)
}
fn serialize_some<T>(self, _value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
Err(Error::WrongType)
}
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
Err(Error::WrongType)
}
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
Err(Error::WrongType)
}
fn serialize_tuple_struct(
self,
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleStruct> {
Err(Error::WrongType)
}
fn serialize_tuple_variant(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleVariant> {
Err(Error::WrongType)
}
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
Err(Error::WrongType)
}
fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
Err(Error::WrongType)
}
fn serialize_struct_variant(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_len: usize,
) -> Result<Self::SerializeStructVariant> {
Err(Error::WrongType)
}
}
#[cfg(test)]
mod test {
use super::*;
use hex_literal::hex;
use serde::Serialize;
use std::collections::BTreeMap;
#[test]
fn to_vec_maps() {
let mut map = BTreeMap::new();
map.insert("foo".to_string(), 123u32);
map.insert("bar".to_string(), 456u32);
let buf = to_vec(&map).unwrap();
assert_eq!(
hex!("70 4103626172 2201C8 4103666F6F 217B 80").as_ref(),
buf.as_slice()
);
}
#[test]
fn to_vec_structs() {
#[derive(Serialize)]
struct Test {
x: bool,
y: u32,
z: Vec<String>,
}
let s = Test {
x: true,
y: 17,
z: vec!["foo".into(), "bar".into()],
};
let buf = to_vec(&s).unwrap();
assert_eq!(
hex!("60 11 2111 60 4103666F6F 4103626172 80 80").as_ref(),
buf.as_slice()
);
}
#[test]
fn to_vec_enums() {
#[derive(Serialize)]
enum Test {
UnitVariant,
NewTypeVariant(u32),
TupleVariant(bool, u32),
StructVariant { x: bool, y: u32 },
}
let e = Test::UnitVariant;
let buf = to_vec(&e).unwrap();
assert_eq!(hex!("2100").as_ref(), buf.as_slice());
let e = Test::NewTypeVariant(17);
let buf = to_vec(&e).unwrap();
assert_eq!(hex!("60 2101 2111 80").as_ref(), buf.as_slice());
let e = Test::TupleVariant(true, 17);
let buf = to_vec(&e).unwrap();
assert_eq!(hex!("60 2102 11 2111 80").as_ref(), buf.as_slice());
let e = Test::StructVariant { x: true, y: 17 };
let buf = to_vec(&e).unwrap();
assert_eq!(hex!("60 2103 11 2111 80").as_ref(), buf.as_slice());
}
#[test]
fn to_vec_options() {
let o: Option<u32> = None;
let buf = to_vec(&o).unwrap();
assert_eq!(hex!("00").as_ref(), buf.as_slice());
let o = Some(17);
let buf = to_vec(&o).unwrap();
assert_eq!(hex!("2111").as_ref(), buf.as_slice());
}
}