use serde::{ser, Serialize}; use crate::bipack_sink::{BipackSink, IntoU64}; use crate::bipack_source::BipackError; use crate::buffer_sink::BufferSink; use crate::error::{Result}; pub struct Serializer { // This string starts empty and JSON is appended as values are serialized. output: S, } pub fn to_bytes(value: &T) -> Result> where T: Serialize + ?Sized, { let mut serializer = Serializer { output: Vec::new() }; value.serialize(&mut serializer)?; Ok(serializer.output) } pub fn to_buffer<'a, T: Serialize>(value: &T, buffer: & 'a mut [u8]) -> Result<& 'a [u8]> { let mut serializer = Serializer { output: BufferSink { buffer, pos: 0}}; value.serialize(&mut serializer)?; Ok(serializer.output.result_slice()) } impl<'a, S: BipackSink> ser::Serializer for &'a mut Serializer { type Ok = (); type Error = BipackError; 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, v: bool) -> Result<()> { self.output.put_u8(if v { 1 } else { 0 })?; Ok(()) } fn serialize_i8(self, v: i8) -> Result<()> { self.output.put_i8(v)?; Ok(()) } fn serialize_i16(self, v: i16) -> Result<()> { self.serialize_i64(i64::from(v))?; Ok(()) } fn serialize_i32(self, v: i32) -> Result<()> { self.serialize_i64(i64::from(v)) } fn serialize_i64(self, v: i64) -> Result<()> { self.output.put_signed(v)?; Ok(()) } fn serialize_u8(self, v: u8) -> Result<()> { self.output.put_u8(v)?; Ok(()) } fn serialize_u16(self, v: u16) -> Result<()> { self.serialize_u64(v.into_u64())?; Ok(()) } fn serialize_u32(self, v: u32) -> Result<()> { self.serialize_u64(v.into())?; Ok(()) } fn serialize_u64(self, v: u64) -> Result<()> { self.output.put_unsigned(v)?; Ok(()) } fn serialize_f32(self, v: f32) -> Result<()> { Err(ser::Error::custom("not implemented")) } fn serialize_f64(self, v: f64) -> Result<()> { Err(ser::Error::custom("not implemented")) } /// Serialize a char as a single-character string, because this is a UTF8-encoded /// char, e.g. variable length: fn serialize_char(self, v: char) -> Result<()> { self.serialize_str(&v.to_string()) } fn serialize_str(self, v: &str) -> Result<()> { self.output.put_str(v)?; Ok(()) } fn serialize_bytes(self, v: &[u8]) -> Result<()> { self.output.put_var_bytes(v)?; Ok(()) } fn serialize_none(self) -> Result<()> { self.serialize_u8(0)?; Ok(()) } fn serialize_some(self, value: &T) -> Result<()> where T: ?Sized + Serialize, { self.serialize_u8(1)?; value.serialize(self) } fn serialize_unit(self) -> Result<()> { Ok(()) } 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( self, _name: &'static str, value: &T, ) -> Result<()> where T: ?Sized + Serialize, { value.serialize(self) } fn serialize_newtype_variant( self, _name: &'static str, _variant_index: u32, variant: &'static str, value: &T, ) -> Result<()> where T: ?Sized + Serialize, { self.serialize_u32(_variant_index)?; value.serialize(self) } /// We expect it to use with vairable-length arrays... fn serialize_seq(self, _len: Option) -> Result { self.output.put_unsigned(_len.unwrap_or(0))?; Ok(self) } fn serialize_tuple(self, len: usize) -> Result { Ok(self) // self.serialize_seq(Some(len)) } fn serialize_tuple_struct( self, _name: &'static str, len: usize, ) -> Result { Ok(self) } fn serialize_tuple_variant( self, _name: &'static str, _variant_index: u32, variant: &'static str, _len: usize, ) -> Result { _variant_index.serialize(&mut *self)?; Ok(self) } fn serialize_map(self, _len: Option) -> Result { self.output.put_unsigned(_len.unwrap_or(0))?; Ok(self) } fn serialize_struct( self, _name: &'static str, len: usize, ) -> Result { // self.serialize_map(Some(len)) Ok(self) } fn serialize_struct_variant( self, _name: &'static str, _variant_index: u32, variant: &'static str, _len: usize, ) -> Result { self.output.put_unsigned(_variant_index)?; Ok(self) } } impl<'a, S: BipackSink> ser::SerializeSeq for &'a mut Serializer { // Must match the `Ok` type of the serializer. type Ok = (); // Must match the `Error` type of the serializer. type Error = BipackError; // Serialize a single element of the sequence. fn serialize_element(&mut self, value: &T) -> Result<()> where T: ?Sized + Serialize, { value.serialize(&mut **self) } // Close the sequence. fn end(self) -> Result<()> { Ok(()) } } impl<'a, S: BipackSink> ser::SerializeTuple for &'a mut Serializer { type Ok = (); type Error = BipackError; fn serialize_element(&mut self, value: &T) -> Result<()> where T: ?Sized + Serialize, { value.serialize(&mut **self) } fn end(self) -> Result<()> { Ok(()) } } impl<'a, S: BipackSink> ser::SerializeTupleStruct for &'a mut Serializer { type Ok = (); type Error = BipackError; fn serialize_field(&mut self, value: &T) -> Result<()> where T: ?Sized + Serialize, { value.serialize(&mut **self) } fn end(self) -> Result<()> { Ok(()) } } impl<'a, S: BipackSink> ser::SerializeTupleVariant for &'a mut Serializer { type Ok = (); type Error = BipackError; fn serialize_field(&mut self, value: &T) -> Result<()> where T: ?Sized + Serialize, { value.serialize(&mut **self) } fn end(self) -> Result<()> { Ok(()) } } impl<'a, S: BipackSink> ser::SerializeMap for &'a mut Serializer { type Ok = (); type Error = BipackError; // The Serde data model allows map keys to be any serializable type. JSON // only allows string keys so the implementation below will produce invalid // JSON if the key serializes as something other than a string. // // A real JSON serializer would need to validate that map keys are strings. // This can be done by using a different Serializer to serialize the key // (instead of `&mut **self`) and having that other serializer only // implement `serialize_str` and return an error on any other data type. fn serialize_key(&mut self, key: &T) -> Result<()> where T: ?Sized + Serialize, { key.serialize(&mut **self) } // It doesn't make a difference whether the colon is printed at the end of // `serialize_key` or at the beginning of `serialize_value`. In this case // the code is a bit simpler having it here. fn serialize_value(&mut self, value: &T) -> Result<()> where T: ?Sized + Serialize, { value.serialize(&mut **self) } fn end(self) -> Result<()> { Ok(()) } } // Structs are like maps in which the keys are constrained to be compile-time // constant strings. impl<'a, S: BipackSink> ser::SerializeStruct for &'a mut Serializer { type Ok = (); type Error = BipackError; fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<()> where T: ?Sized + Serialize, { value.serialize(&mut **self) } fn end(self) -> Result<()> { Ok(()) } } impl<'a, S: BipackSink> ser::SerializeStructVariant for &'a mut Serializer { type Ok = (); type Error = BipackError; fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<()> where T: ?Sized + Serialize, { value.serialize(&mut **self) } fn end(self) -> Result<()> { Ok(()) } } #[cfg(test)] mod test { use std::collections::HashMap; use std::string::FromUtf8Error; use serde::Serialize; use crate::bipack_source::{BipackError, BipackSource, SliceSource}; use crate::error; use crate::ser::to_bytes; use crate::tools::{to_dump, to_hex}; #[test] fn test_struct() -> Result<(), BipackError> { #[derive(Serialize)] struct Test { int: u32, seq: Vec<&'static str>, } let test = Test { int: 17, seq: vec!["a", "b"], }; let x = to_bytes(&test).unwrap(); println!("!:\n{}", to_dump(&x)); // let y = x.clone(); // let z = x.clone(); let mut src = SliceSource::from(&x); assert_eq!(test.int, src.get_unsigned()? as u32); assert_eq!(test.seq.len(), src.get_unsigned()? as usize); assert_eq!(test.seq[0], src.get_str()?); assert_eq!(test.seq[1], src.get_str()?); Ok(()) } #[test] fn test_enum() -> Result<(), FromUtf8Error> { #[derive(Serialize)] enum E { Unit, Unit2, Newtype(u32), Tuple(u32, u32), Struct { a: u32 }, } let u = E::Unit; println!("u:{}", to_dump(to_bytes(&u).unwrap().as_slice())); assert_eq!("00", to_hex(to_bytes(&u).unwrap())?); let u2 = E::Unit2; println!("u:{}", to_dump(to_bytes(&u2).unwrap().as_slice())); let nt = E::Newtype(17); println!("u:{}", to_dump(to_bytes(&nt).unwrap().as_slice())); assert_eq!("08 44", to_hex(to_bytes(&nt).unwrap())?); let t = E::Tuple(7, 17); println!("u:{}", to_dump(to_bytes(&t).unwrap().as_slice())); assert_eq!("0c 1c 44", to_hex(to_bytes(&t).unwrap())?); let t = E::Struct { a: 17 }; println!("u:{}", to_dump(to_bytes(&t).unwrap().as_slice())); assert_eq!("10 44", to_hex(to_bytes(&t).unwrap())?); // let expected = r#""Unit""#; // assert_eq!(to_string(&u).unwrap(), expected); // // let n = E::Newtype(1); // let expected = r#"{"Newtype":1}"#; // assert_eq!(to_string(&n).unwrap(), expected); // // let t = E::Tuple(1, 2); // let expected = r#"{"Tuple":[1,2]}"#; // assert_eq!(to_string(&t).unwrap(), expected); // // let s = E::Struct { a: 1 }; // let expected = r#"{"Struct":{"a":1}}"#; // assert_eq!(to_string(&s).unwrap(), expected); Ok(()) } #[test] fn test_map() -> error::Result<()> { let mut src = HashMap::new(); // src.insert("foo", 1); src.insert("foo", 42); src.insert("bar", 1); src.insert("baz", 17); let packed = to_bytes(&src)?; println!("{}", to_dump(&packed)); Ok(()) } }