use serde::{
ser::{
self, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTuple,
SerializeTupleStruct, SerializeTupleVariant,
},
Serialize,
};
use std::convert::TryFrom;
use std::io::Write;
use super::error::{Error, MapError, Result};
type Ok = ();
pub struct Serializer<W: Write> {
output: W,
}
impl<W: Write> Serializer<W> {
pub fn new(write: W) -> Serializer<W> {
Serializer { output: write }
}
}
pub fn to_vec<T: Serialize + ?Sized>(value: &T) -> Result<Vec<u8>> {
let mut vec = Vec::new();
write_to(value, &mut vec)?;
Ok(vec)
}
pub fn write_to<T: Serialize + ?Sized, W: Write>(value: &T, write: W) -> Result<()> {
let mut serializer = Serializer::new(write);
value.serialize(&mut serializer)
}
fn try_convert(len: Option<usize>) -> Result<u32> {
match len {
Some(count) => {
let length = u32::try_from(count).map_err(|_| Error::SequenceTooLong(count))?;
Ok(length)
}
None => Err(Error::UnknownLength),
}
}
fn convert_variant_index(index: u32) -> Result<u16> {
u16::try_from(index).map_err(|_| Error::TooManyVariants(index))
}
impl<'a, T: Write> ser::Serializer for &'a mut Serializer<T> {
type Ok = Ok;
type Error = Error;
type SerializeSeq = Self;
type SerializeTuple = Self;
type SerializeTupleVariant = Self;
type SerializeTupleStruct = Self;
type SerializeMap = Self;
type SerializeStruct = Self;
type SerializeStructVariant = Self;
#[allow(clippy::bool_to_int_with_if)]
fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
self.output
.write_all(&[if v { 1 } else { 0 }])
.map_error()?;
Ok(())
}
fn serialize_i8(self, v: i8) -> Result<Self::Ok> {
self.output.write_all(&v.to_le_bytes()).map_error()?;
Ok(())
}
fn serialize_i16(self, v: i16) -> Result<Self::Ok> {
self.output.write_all(&v.to_le_bytes()).map_error()?;
Ok(())
}
fn serialize_i32(self, v: i32) -> Result<Self::Ok> {
self.output.write_all(&v.to_le_bytes()).map_error()?;
Ok(())
}
fn serialize_i64(self, v: i64) -> Result<Self::Ok> {
self.output.write_all(&v.to_le_bytes()).map_error()?;
Ok(())
}
fn serialize_i128(self, v: i128) -> Result<Self::Ok> {
self.output.write_all(&v.to_le_bytes()).map_error()?;
Ok(())
}
fn serialize_u8(self, v: u8) -> Result<Self::Ok> {
self.output.write_all(&[v]).map_error()?;
Ok(())
}
fn serialize_u16(self, v: u16) -> Result<Self::Ok> {
self.output.write_all(&v.to_le_bytes()).map_error()?;
Ok(())
}
fn serialize_u32(self, v: u32) -> Result<Self::Ok> {
self.output.write_all(&v.to_le_bytes()).map_error()?;
Ok(())
}
fn serialize_u64(self, v: u64) -> Result<Self::Ok> {
self.output.write_all(&v.to_le_bytes()).map_error()?;
Ok(())
}
fn serialize_u128(self, v: u128) -> Result<Self::Ok> {
self.output.write_all(&v.to_le_bytes()).map_error()?;
Ok(())
}
fn serialize_f32(self, v: f32) -> Result<Self::Ok> {
self.output.write_all(&v.to_le_bytes()).map_error()?;
Ok(())
}
fn serialize_f64(self, v: f64) -> Result<Self::Ok> {
self.output.write_all(&v.to_le_bytes()).map_error()?;
Ok(())
}
fn serialize_char(self, c: char) -> Result<Self::Ok> {
self.output.write_all(&[c as u8]).map_error()?;
Ok(())
}
fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok> {
let len = v.len() as u32;
self.output.write_all(&len.to_le_bytes()).map_error()?;
self.output.write_all(v).map_error()?;
Ok(())
}
fn serialize_str(self, v: &str) -> Result<Self::Ok> {
self.serialize_bytes(v.as_bytes())
}
fn serialize_none(self) -> Result<Self::Ok> {
self.serialize_bool(false)?;
Ok(())
}
fn serialize_some<U: ?Sized + Serialize>(self, value: &U) -> Result<Self::Ok> {
self.serialize_bool(true)?;
value.serialize(self)?;
Ok(())
}
fn serialize_unit(self) -> Result<()> {
Ok(())
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> {
self.serialize_unit()
}
fn serialize_unit_variant(
self,
_name: &'static str,
variant_index: u32,
_variant: &'static str,
) -> Result<Self::Ok> {
let index = convert_variant_index(variant_index)?;
self.serialize_u16(index)?;
Ok(())
}
fn serialize_newtype_struct<U: ?Sized + Serialize>(
self,
_name: &'static str,
value: &U,
) -> Result<Self::Ok> {
value.serialize(self)?;
Ok(())
}
fn serialize_newtype_variant<U: ?Sized + Serialize>(
self,
_name: &'static str,
variant_index: u32,
_variant: &'static str,
value: &U,
) -> Result<Self::Ok> {
let index = convert_variant_index(variant_index)?;
self.serialize_u16(index)?;
value.serialize(self)?;
Ok(())
}
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
let length = try_convert(len)?;
self.serialize_u32(length)?;
Ok(self)
}
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
Ok(self)
}
fn serialize_tuple_struct(
self,
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleStruct> {
Ok(self)
}
fn serialize_tuple_variant(
self,
_name: &'static str,
variant_index: u32,
_variant: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleStruct> {
let index = convert_variant_index(variant_index)?;
self.serialize_u16(index)?;
Ok(self)
}
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
let length = try_convert(len)?;
self.serialize_u32(length)?;
Ok(self)
}
fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
Ok(self)
}
fn serialize_struct_variant(
self,
_name: &'static str,
variant_index: u32,
_variant: &'static str,
_len: usize,
) -> Result<Self::SerializeStructVariant> {
let index = convert_variant_index(variant_index)?;
self.serialize_u16(index)?;
Ok(self)
}
fn is_human_readable(&self) -> bool {
false
}
}
impl<'a, W: Write> SerializeSeq for &'a mut Serializer<W> {
type Ok = Ok;
type Error = Error;
fn serialize_element<U: ?Sized + Serialize>(&mut self, value: &U) -> Result<Ok> {
value.serialize(&mut **self)?;
Ok(())
}
fn end(self) -> Result<Ok> {
Ok(())
}
}
impl<'a, W: Write> SerializeTuple for &'a mut Serializer<W> {
type Ok = Ok;
type Error = Error;
fn serialize_element<U: ?Sized + Serialize>(&mut self, value: &U) -> Result<Ok> {
value.serialize(&mut **self)?;
Ok(())
}
fn end(self) -> Result<Ok> {
Ok(())
}
}
impl<'a, W: Write> SerializeTupleStruct for &'a mut Serializer<W> {
type Ok = Ok;
type Error = Error;
fn serialize_field<U: ?Sized + Serialize>(&mut self, value: &U) -> Result<Ok> {
value.serialize(&mut **self)?;
Ok(())
}
fn end(self) -> Result<Ok> {
Ok(())
}
}
impl<'a, W: Write> SerializeTupleVariant for &'a mut Serializer<W> {
type Ok = Ok;
type Error = Error;
fn serialize_field<U: ?Sized + Serialize>(&mut self, value: &U) -> Result<Ok> {
value.serialize(&mut **self)?;
Ok(())
}
fn end(self) -> Result<Ok> {
Ok(())
}
}
impl<'a, W: Write> SerializeMap for &'a mut Serializer<W> {
type Ok = Ok;
type Error = Error;
fn serialize_key<U: ?Sized + Serialize>(&mut self, key: &U) -> Result<Ok> {
key.serialize(&mut **self)?;
Ok(())
}
fn serialize_value<U: ?Sized + Serialize>(&mut self, value: &U) -> Result<Ok> {
value.serialize(&mut **self)?;
Ok(())
}
fn end(self) -> Result<Ok> {
Ok(())
}
}
impl<'a, W: Write> SerializeStruct for &'a mut Serializer<W> {
type Ok = Ok;
type Error = Error;
fn serialize_field<U: ?Sized + Serialize>(
&mut self,
_key: &'static str,
value: &U,
) -> Result<Ok> {
value.serialize(&mut **self)?;
Ok(())
}
fn end(self) -> Result<Ok> {
Ok(())
}
}
impl<'a, W: Write> SerializeStructVariant for &'a mut Serializer<W> {
type Ok = Ok;
type Error = Error;
fn serialize_field<U: ?Sized + Serialize>(
&mut self,
_key: &'static str,
value: &U,
) -> Result<Ok> {
value.serialize(&mut **self)?;
Ok(())
}
fn end(self) -> Result<Ok> {
Ok(())
}
}
#[cfg(test)]
mod test {
use super::Result;
use serde::Serialize;
#[test]
fn serialize_bool() -> Result<()> {
{
let buffer = super::to_vec(&true)?;
assert_eq!(vec![1], buffer);
}
{
let buffer = super::to_vec(&false)?;
assert_eq!(vec![0], buffer);
}
Ok(())
}
#[test]
fn serialize_i8() -> Result<()> {
{
let buffer = super::to_vec(&5i8)?;
assert_eq!(vec![0b00000101], buffer);
}
{
let value: i8 = -1;
let buffer = super::to_vec(&value)?;
assert_eq!(vec![0b11111111], buffer);
}
Ok(())
}
#[test]
fn serialize_i16() -> Result<()> {
{
let buffer = super::to_vec(&1i16)?;
assert_eq!(vec![0x01, 0x00], buffer);
}
{
let value: i16 = -2;
let buffer = super::to_vec(&value)?;
assert_eq!(vec![0xFE, 0xFF], buffer);
}
Ok(())
}
#[test]
fn serialize_i32() -> Result<()> {
{
let buffer = super::to_vec(&1i32)?;
assert_eq!(vec![0x01, 0x00, 0x00, 0x00], buffer);
}
{
let value: i32 = -2;
let buffer = super::to_vec(&value)?;
assert_eq!(vec![0xFE, 0xFF, 0xFF, 0xFF], buffer);
}
Ok(())
}
#[test]
fn serialize_i64() -> Result<()> {
{
let buffer = super::to_vec(&1i64)?;
assert_eq!(vec![0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], buffer);
}
{
let value: i64 = -2;
let buffer = super::to_vec(&value)?;
assert_eq!(vec![0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF], buffer);
}
Ok(())
}
#[test]
fn serialize_i128() -> Result<()> {
{
let buffer = super::to_vec(&1i128)?;
assert_eq!(
vec![
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00
],
buffer
);
}
{
let value: i128 = -2;
let buffer = super::to_vec(&value)?;
assert_eq!(
vec![
0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF
],
buffer
);
}
Ok(())
}
#[test]
fn serialize_u8() -> Result<()> {
let value: u8 = 42;
let buffer = super::to_vec(&value)?;
assert_eq!(vec![value], buffer);
Ok(())
}
#[test]
fn serialize_u16() -> Result<()> {
let buffer = super::to_vec(&1u16)?;
assert_eq!(vec![0x01, 0x00], buffer);
Ok(())
}
#[test]
fn serialize_u32() -> Result<()> {
let buffer = super::to_vec(&1u32)?;
assert_eq!(vec![0x01, 0x00, 0x00, 0x00], buffer);
Ok(())
}
#[test]
fn serialize_u64() -> Result<()> {
let buffer = super::to_vec(&1u64)?;
assert_eq!(vec![0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], buffer);
Ok(())
}
#[test]
fn serialize_u128() -> Result<()> {
let buffer = super::to_vec(&1u128)?;
assert_eq!(
vec![
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00
],
buffer
);
Ok(())
}
#[test]
fn serialize_f32() -> Result<()> {
let buffer = super::to_vec(&0.15625f32)?;
assert_eq!(vec![0x00, 0x00, 0x20, 0x3E], buffer);
Ok(())
}
#[test]
fn serialize_f64() -> Result<()> {
let buffer = super::to_vec(&1f64)?;
assert_eq!(vec![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F], buffer);
Ok(())
}
#[test]
fn serialize_char() -> Result<()> {
let c: char = '*';
let buffer = super::to_vec(&c)?;
assert_eq!(vec![42], buffer);
Ok(())
}
#[test]
fn serialize_bytes() -> Result<()> {
let mut bytes: Vec<u8> = vec![41, 23, 72, 61];
let buffer = super::to_vec(bytes.as_slice())?;
let length = bytes.len() as u32;
let mut expected = length.to_le_bytes().to_vec();
expected.append(&mut bytes);
assert_eq!(expected, buffer);
Ok(())
}
#[test]
fn serialize_str() -> Result<()> {
let message = "vapid 😑";
let buffer = super::to_vec(message)?;
assert_eq!(
vec![10, 0, 0, 0, 118, 97, 112, 105, 100, 32, 240, 159, 152, 145],
buffer
);
Ok(())
}
#[test]
fn serialize_none() -> Result<()> {
let none: Option<i32> = Option::None;
let buffer = super::to_vec(&none)?;
assert_eq!(vec![0], buffer);
Ok(())
}
#[test]
fn serialize_some() -> Result<()> {
let some: Option<i32> = Option::Some(0x02D8);
let buffer = super::to_vec(&some)?;
assert_eq!(vec![0x01, 0xD8, 0x02, 0x00, 0x00], buffer);
Ok(())
}
#[test]
fn serialize_unit() -> Result<()> {
let buffer = super::to_vec(&())?;
let expected: Vec<u8> = Vec::new();
assert_eq!(expected, buffer);
Ok(())
}
#[test]
fn serialize_unit_struct() -> Result<()> {
#[derive(Serialize)]
struct UnitStruct;
let test = UnitStruct {};
let buffer = super::to_vec(&test)?;
let expected: Vec<u8> = Vec::new();
assert_eq!(expected, buffer);
Ok(())
}
#[test]
fn serialize_unit_variant() -> Result<()> {
#[derive(Serialize)]
#[allow(dead_code)]
enum Matter {
Condensate,
Solid,
Liquid,
Gas,
Plasma,
Cat,
}
let test = Matter::Liquid;
let buffer = super::to_vec(&test)?;
assert_eq!(vec![0x02, 0x00], buffer);
Ok(())
}
#[test]
fn serialize_newtype_struct() -> Result<()> {
#[derive(Serialize)]
struct Score(u16);
let score = Score(512);
let buffer = super::to_vec(&score)?;
assert_eq!(vec![0x00, 0x02], buffer);
Ok(())
}
#[test]
fn serialize_newtype_variant() -> Result<()> {
#[derive(Serialize)]
#[allow(dead_code)]
enum Currency {
Usd(i32),
Btc(i32),
Fil(i32),
Eth(i32),
}
let value = Currency::Fil(1024);
let buffer = super::to_vec(&value)?;
let expected = vec![
0x02, 0x00, 0x00, 0x04, 0x00, 0x00, ];
assert_eq!(expected, buffer);
Ok(())
}
#[test]
fn serialize_unit_struct_variant() -> Result<()> {
#[derive(Serialize)]
#[allow(dead_code)]
enum UnitStructVariant {
Zeroth {},
First {},
Second {},
Third {},
}
let test = UnitStructVariant::Second {};
let buffer = super::to_vec(&test)?;
assert_eq!(vec![2, 0], buffer);
Ok(())
}
#[test]
fn serialize_tuple() -> Result<()> {
let value = (5u16, -1i8);
let buffer = super::to_vec(&value)?;
assert_eq!(vec![0x05, 0x00 , 0xFF ], buffer);
Ok(())
}
#[test]
fn serialize_tuple_struct() -> Result<()> {
#[derive(Serialize)]
struct Contrived(i8, String);
let value = Contrived(-2, "-2".to_string());
let buffer = super::to_vec(&value)?;
let expected = vec![
0xFE, 0x02, 0x00, 0x00, 0x00, 0x2D, 0x32, ];
assert_eq!(expected, buffer);
Ok(())
}
#[test]
fn serialize_tuple_variant() -> Result<()> {
#[derive(Serialize)]
#[allow(dead_code)]
enum ByteVector {
Dim2(u8, u8),
Dim3(u8, u8, u8),
}
let value = ByteVector::Dim3(5, 9, 42);
let buffer = super::to_vec(&value)?;
let expected = vec![
0x01, 0x00, 0x05, 0x09, 0x2A, ];
assert_eq!(expected, buffer);
Ok(())
}
#[test]
fn serialize_map() -> Result<()> {
use std::collections::HashMap;
#[derive(PartialEq, Eq, Hash, Serialize)]
enum Color {
Red,
Blue,
}
let mut map: HashMap<Color, u16> = HashMap::new();
map.insert(Color::Red, 5);
map.insert(Color::Blue, 256);
let buffer = super::to_vec(&map)?;
assert_eq!(12, buffer.len());
assert_eq!(vec![0x02, 0x00, 0x00, 0x00], &buffer[..4]);
let mut expected_map: HashMap<[u8; 2], [u8; 2]> = HashMap::new();
expected_map.insert([0x00, 0x00], [0x05, 0x00]);
expected_map.insert([0x01, 0x00], [0x00, 0x01]);
assert_eq!(expected_map.get(&buffer[4..6]).unwrap(), &buffer[6..8]);
assert_eq!(expected_map.get(&buffer[8..10]).unwrap(), &buffer[10..12]);
Ok(())
}
#[test]
fn serialize_struct() -> Result<()> {
#[derive(Serialize)]
struct Bag {
name: &'static str,
weight: u16,
value: i8,
}
let value = Bag {
name: "box",
weight: 10,
value: -1,
};
let buffer = super::to_vec(&value)?;
let expected = vec![
0x03, 0x00, 0x00, 0x00, 'b' as u8, 'o' as u8, 'x' as u8, 0x0A, 0x00, 0xFF, ];
assert_eq!(expected, buffer);
Ok(())
}
#[test]
fn serialize_struct_variant() -> Result<()> {
#[derive(Serialize)]
#[allow(dead_code)]
enum Shape {
Rectangle {
upper_left_corner: (u16, u16),
width: u16,
height: u16,
},
Circle {
center: (u16, u16),
radius: u16,
},
}
let value = Shape::Circle {
center: (0x1D42, 0x9FE0),
radius: 0xA100,
};
let buffer = super::to_vec(&value)?;
let expected = vec![
0x01, 0x00, 0x42, 0x1D, 0xE0, 0x9F, 0x00, 0xA1, ];
assert_eq!(expected, buffer);
Ok(())
}
}