use std::io::Write; use std::convert::TryFrom; use serde::{ ser::{ self, SerializeSeq, SerializeTuple, SerializeTupleStruct, SerializeTupleVariant, SerializeMap, SerializeStruct, SerializeStructVariant, }, Serialize, }; use super::error::{Error, Result, MapError}; type Ok = (); pub struct Serializer { output: T, } pub fn to_vec(value: &T) -> Result> { let mut serializer = Serializer { output: Vec::new()}; value.serialize(&mut serializer)?; Ok(serializer.output) } fn try_convert(len: Option) -> Result { match len { Some(count) => { let length = u32::try_from(count).or_else(|_| Err(Error::SequenceTooLong(count)))?; Ok(length) }, None => Err(Error::UnknownLength), } } impl<'a, T: Write> ser::Serializer for &'a mut Serializer { 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; /// A bool is serialized by writing the byte 1 if true and 0 if false. fn serialize_bool(self, v: bool) -> Result { self.output.write_all(&[if v { 1 } else { 0 }]).map_error()?; Ok(()) } /// The output format of a signed byte is two's complement, so we can just output /// Rust's binary representation. fn serialize_i8(self, v: i8) -> Result { self.output.write_all(&v.to_le_bytes()).map_error()?; Ok(()) } /// The output format of a signed integer is two's complement, so we can just output /// Rust's binary representation in little endian order. fn serialize_i16(self, v: i16) -> Result { self.output.write_all(&v.to_le_bytes()).map_error()?; Ok(()) } /// The output format of a signed integer is two's complement, so we can just output /// Rust's binary representation in little endian order. fn serialize_i32(self, v: i32) -> Result { self.output.write_all(&v.to_le_bytes()).map_error()?; Ok(()) } /// The output format of a signed integer is two's complement, so we can just output /// Rust's binary representation in little endian order. fn serialize_i64(self, v: i64) -> Result { self.output.write_all(&v.to_le_bytes()).map_error()?; Ok(()) } /// The output format of a signed integer is two's complement, so we can just output /// Rust's binary representation in little endian order. fn serialize_i128(self, v: i128) -> Result { self.output.write_all(&v.to_le_bytes()).map_error()?; Ok(()) } /// The given byte is written directly to the output. fn serialize_u8(self, v: u8) -> Result { self.output.write_all(&[v]).map_error()?; Ok(()) } /// The underlying bytes of the given unsigned integer are written to the output in little /// endian order. fn serialize_u16(self, v: u16) -> Result { self.output.write_all(&v.to_le_bytes()).map_error()?; Ok(()) } /// The underlying bytes of the given unsigned integer are written to the output in little /// endian order. fn serialize_u32(self, v: u32) -> Result { self.output.write_all(&v.to_le_bytes()).map_error()?; Ok(()) } /// The underlying bytes of the given unsigned integer are written to the output in little /// endian order. fn serialize_u64(self, v: u64) -> Result { self.output.write_all(&v.to_le_bytes()).map_error()?; Ok(()) } /// The underlying bytes of the given unsigned integer are written to the output in little /// endian order. fn serialize_u128(self, v: u128) -> Result { self.output.write_all(&v.to_le_bytes()).map_error()?; Ok(()) } /// Since the output format is IEEE 754, we can just write the underlying bytes to the output /// in little endian order. fn serialize_f32(self, v: f32) -> Result { self.output.write_all(&v.to_le_bytes()).map_error()?; Ok(()) } /// Since the output format is IEEE 754, we can just write the underlying bytes to the output /// in little endian order. fn serialize_f64(self, v: f64) -> Result { self.output.write_all(&v.to_le_bytes()).map_error()?; Ok(()) } /// The given char is cast to a u8 then written to the output. fn serialize_char(self, c: char) -> Result { self.output.write_all(&[c as u8]).map_error()?; Ok(()) } /// A slice of bytes is stored by first writing its length (in LE order) and then the slice. fn serialize_bytes(self, v: &[u8]) -> Result { let len = v.len() as u32; self.output.write_all(&len.to_le_bytes()).map_error()?; self.output.write_all(v).map_error()?; Ok(()) } /// A str is just serialized as a sequence of UTF8 bytes. fn serialize_str(self, v: &str) -> Result { self.serialize_bytes(v.as_bytes()) } /// The none variant is stored as a zero byte. fn serialize_none(self) -> Result { self.output.write_all(&[0]).map_error()?; Ok(()) } /// A some variant is just stored using the representation of its value. fn serialize_some(self, value: &U) -> Result { value.serialize(self)?; Ok(()) } /// The unit is a type which can be represented with zero bytes, so we faithfully represent it /// as nothing. fn serialize_unit(self) -> Result<()> { Ok(()) } /// Forwards to serialize_unit. fn serialize_unit_struct(self, _name: &'static str) -> Result { self.serialize_unit() } /// The index of the unit variant is written to the output. fn serialize_unit_variant( self, _name: &'static str, variant_index: u32, _variant: &'static str ) -> Result { self.serialize_u32(variant_index)?; Ok(()) } /// The value of the newtype struct is serialized and its name is ignored. fn serialize_newtype_struct( self, _name: &'static str, value: &U ) -> Result { value.serialize(self)?; Ok(()) } /// The index of the variant is serialized and written out, followed by the serialization of /// its value. fn serialize_newtype_variant( self, _name: &'static str, variant_index: u32, _variant: &'static str, value: &U ) -> Result { self.serialize_u32(variant_index)?; value.serialize(self)?; Ok(()) } fn serialize_seq(self, len: Option) -> Result { let length = try_convert(len)?; self.serialize_u32(length)?; Ok(self) } /// A tuples length is not stored, only its entries. fn serialize_tuple(self, _len: usize) -> Result { Ok(self) } /// A tuple struct is serialized the same way as a tuple, its name is ignore. fn serialize_tuple_struct( self, _name: &'static str, _len: usize ) -> Result { Ok(self) } /// The variant index is stored before the tuples values. fn serialize_tuple_variant( self, _name: &'static str, variant_index: u32, _variant: &'static str, _len: usize ) -> Result { self.serialize_u32(variant_index)?; Ok(self) } /// The number of entries in the map is stored as a u32 prior to serializing the key value /// pairs in the map. If there are more entries than a u32 can represent, then an error is /// returned. fn serialize_map(self, len: Option) -> Result { let length = try_convert(len)?; self.serialize_u32(length)?; Ok(self) } /// Since the members of a struct a known at compile time, no additional information is stored. fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { Ok(self) } /// The variant index is stored before the struct's members. fn serialize_struct_variant( self, _name: &'static str, variant_index: u32, _variant: &'static str, _len: usize ) -> Result { self.serialize_u32(variant_index)?; Ok(self) } } impl<'a, T: Write> SerializeSeq for &'a mut Serializer { type Ok = Ok; type Error = Error; fn serialize_element(&mut self, value: &U) -> Result { value.serialize(&mut **self)?; Ok(()) } /// No marker is added to the end of the sequence because we know its length. fn end(self) -> Result { Ok(()) } } impl<'a, T: Write> SerializeTuple for &'a mut Serializer { type Ok = Ok; type Error = Error; fn serialize_element(&mut self, value: &U) -> Result { value.serialize(&mut **self)?; Ok(()) } fn end(self) -> Result { Ok(()) } } impl<'a, T: Write> SerializeTupleStruct for &'a mut Serializer { type Ok = Ok; type Error = Error; fn serialize_field(&mut self, value: &U) -> Result { value.serialize(&mut **self)?; Ok(()) } fn end(self) -> Result { Ok(()) } } impl<'a, T: Write> SerializeTupleVariant for &'a mut Serializer { type Ok = Ok; type Error = Error; fn serialize_field(&mut self, value: &U) -> Result { value.serialize(&mut **self)?; Ok(()) } fn end(self) -> Result { Ok(()) } } impl<'a, T: Write> SerializeMap for &'a mut Serializer { type Ok = Ok; type Error = Error; fn serialize_key(&mut self, key: &U) -> Result { key.serialize(&mut **self)?; Ok(()) } fn serialize_value(&mut self, value: &U) -> Result { value.serialize(&mut **self)?; Ok(()) } fn end(self) -> Result { Ok(()) } } impl<'a, T: Write> SerializeStruct for &'a mut Serializer { type Ok = Ok; type Error = Error; fn serialize_field( &mut self, _key: &'static str, value: &U) -> Result { value.serialize(&mut **self)?; Ok(()) } fn end(self) -> Result { Ok(()) } } impl<'a, T: Write> SerializeStructVariant for &'a mut Serializer { type Ok = Ok; type Error = Error; fn serialize_field( &mut self, _key: &'static str, value: &U) -> Result { value.serialize(&mut **self)?; Ok(()) } fn end(self) -> Result { Ok(()) } } mod test { use super::Result; use super::super::super::{ VersionedBlock, Block, ReadCap, WriteCap, Certificate, Hash, Signature, EnvelopedKey }; 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 = 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 = Option::None; let buffer = super::to_vec(&none)?; assert_eq!(vec![0], buffer); Ok(()) } #[test] fn serialize_some() -> Result<()> { // Sometimes I use decimal sometimes I use hex. So what, what to fight about it? let some: Option = Option::Some(0x02D8); let buffer = super::to_vec(&some)?; assert_eq!(vec![0xD8, 0x02, 0x00, 0x00], buffer); Ok(()) } #[test] fn serialize_unit() -> Result<()> { let buffer = super::to_vec(&())?; let expected: Vec = 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 = Vec::new(); assert_eq!(expected, buffer); Ok(()) } #[test] fn serialize_unit_struct_variant() -> Result<()> { #[derive(Serialize)] enum UnitStructVariant { Zeroth {}, First {}, Second {}, Third {} } let test = UnitStructVariant::Second {}; let buffer = super::to_vec(&test)?; assert_eq!(vec![2, 0, 0, 0], 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)] 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, 0x00, // The variant index. 0x00, 0x04, 0x00, 0x00 // The value contained within. ]; assert_eq!(expected, 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, // The value -2. 0x02, 0x00, 0x00, 0x00, // The length of the string. 0x2D, 0x32 // The characters '-' and '2'. ]; assert_eq!(expected, buffer); Ok(()) } }