/// The main core of the parser. /// /// TODO: split into more module (error, trait, base type) use std::io::{Cursor, Read, Seek, SeekFrom, Write}; pub use androscalpel_serializer_derive::*; pub mod leb; pub mod string; pub use leb::*; pub use string::*; #[derive(Debug, PartialEq, Eq)] pub enum Error { InputTooSmall(String), // TODO: find a better name SerializationError(String), DeserializationError(String), InvalidStringEncoding(String), } pub type Result = core::result::Result; pub trait ReadSeek: Read + Seek {} impl ReadSeek for T {} impl std::fmt::Display for Error { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { Self::InputTooSmall(msg) => write!(f, "Error: {}", msg), Self::SerializationError(msg) => write!(f, "Error: {}", msg), Self::DeserializationError(msg) => write!(f, "Error: {}", msg), Self::InvalidStringEncoding(msg) => write!(f, "Error: {}", msg), } } } impl std::error::Error for Error {} pub trait Serializable { fn serialize(&self, output: &mut dyn Write) -> Result<()>; fn deserialize(input: &mut dyn ReadSeek) -> Result where Self: Sized; fn size(&self) -> usize; fn serialize_to_vec(&self) -> Result> { let mut output = Cursor::new(Vec::::new()); self.serialize(&mut output)?; Ok(output.into_inner()) } fn deserialize_from_slice(input: &[u8]) -> Result where Self: Sized, { let mut buffer = Cursor::new(input); Self::deserialize(&mut buffer) } } pub trait SerializableUntil { fn serialize(&self, output: &mut dyn Write, end_val: U) -> Result<()>; fn deserialize(input: &mut dyn ReadSeek, end_val: U) -> Result where Self: Sized; fn size(&self, end_val: U) -> usize; fn serialize_to_vec(&self, end_val: U) -> Result> { let mut output = Cursor::new(Vec::::new()); self.serialize(&mut output, end_val)?; Ok(output.into_inner()) } fn deserialize_from_slice(input: &[u8], end_val: U) -> Result where Self: Sized, { let mut buffer = Cursor::new(input); Self::deserialize(&mut buffer, end_val) } } impl SerializableUntil for Vec { fn serialize(&self, output: &mut dyn Write, end_val: U) -> Result<()> { for data in self { data.serialize(output)?; } end_val.serialize(output) } fn deserialize(input: &mut dyn ReadSeek, end_val: U) -> Result where Self: Sized, { let mut data = Self::new(); loop { let pos = input.stream_position().map_err(|err| { Error::SerializationError(format!("Failled to get position in steam: {err}")) })?; match U::deserialize(input) { Ok(val) if val == end_val => break Ok(data), Err(err) => break Err(err), Ok(_) => input.seek(SeekFrom::Start(pos)).map_err(|err| { Error::SerializationError(format!("Failled to get to position in steam: {err}")) })?, }; data.push(D::deserialize(input)?); } } fn size(&self, end_val: U) -> usize { self.iter().map(|data| data.size()).sum::() + end_val.size() } } impl Serializable for u8 { fn serialize(&self, output: &mut dyn Write) -> Result<()> { output.write_all(&self.to_be_bytes()).map_err(|err| { Error::SerializationError(format!("Failed to write serialize u8 to output: {err}")) })?; Ok(()) } fn deserialize(input: &mut dyn ReadSeek) -> Result { let mut buffer = [0u8; 1]; input.read_exact(&mut buffer).map_err(|_| { Error::InputTooSmall("Failed to read all bytes for u8 from the input".into()) })?; Ok(Self::from_be_bytes(buffer)) } fn size(&self) -> usize { 1 } } impl Serializable for i8 { fn serialize(&self, output: &mut dyn Write) -> Result<()> { output.write_all(&self.to_be_bytes()).map_err(|err| { Error::SerializationError(format!("Failed to write serialize i8 to output: {err}")) })?; Ok(()) } fn deserialize(input: &mut dyn ReadSeek) -> Result { let mut buffer = [0u8; 1]; input.read_exact(&mut buffer).map_err(|_| { Error::InputTooSmall("Failed to read all bytes for i8 from the input".into()) })?; Ok(Self::from_be_bytes(buffer)) } fn size(&self) -> usize { 1 } } impl Serializable for u16 { fn serialize(&self, output: &mut dyn Write) -> Result<()> { output.write_all(&self.to_be_bytes()).map_err(|err| { Error::SerializationError(format!("Failed to write serialize u16 to output: {err}")) })?; Ok(()) } fn deserialize(input: &mut dyn ReadSeek) -> Result { let mut buffer = [0u8; 2]; input.read_exact(&mut buffer).map_err(|_| { Error::InputTooSmall("Failed to read all bytes for u16 from the input".into()) })?; Ok(Self::from_be_bytes(buffer)) } fn size(&self) -> usize { 2 } } impl Serializable for i16 { fn serialize(&self, output: &mut dyn Write) -> Result<()> { output.write_all(&self.to_be_bytes()).map_err(|err| { Error::SerializationError(format!("Failed to write serialize i16 to output: {err}")) })?; Ok(()) } fn deserialize(input: &mut dyn ReadSeek) -> Result { let mut buffer = [0u8; 2]; input.read_exact(&mut buffer).map_err(|_| { Error::InputTooSmall("Failed to read all bytes for i16 from the input".into()) })?; Ok(Self::from_be_bytes(buffer)) } fn size(&self) -> usize { 2 } } impl Serializable for u32 { fn serialize(&self, output: &mut dyn Write) -> Result<()> { output.write_all(&self.to_be_bytes()).map_err(|err| { Error::SerializationError(format!("Failed to write serialize u32 to output: {err}")) })?; Ok(()) } fn deserialize(input: &mut dyn ReadSeek) -> Result { let mut buffer = [0u8; 4]; input.read_exact(&mut buffer).map_err(|_| { Error::InputTooSmall("Failed to read all bytes for u32 from the input".into()) })?; Ok(Self::from_be_bytes(buffer)) } fn size(&self) -> usize { 4 } } impl Serializable for i32 { fn serialize(&self, output: &mut dyn Write) -> Result<()> { output.write_all(&self.to_be_bytes()).map_err(|err| { Error::SerializationError(format!("Failed to write serialize i32 to output: {err}")) })?; Ok(()) } fn deserialize(input: &mut dyn ReadSeek) -> Result { let mut buffer = [0u8; 4]; input.read_exact(&mut buffer).map_err(|_| { Error::InputTooSmall("Failed to read all bytes for i32 from the input".into()) })?; Ok(Self::from_be_bytes(buffer)) } fn size(&self) -> usize { 4 } } impl Serializable for u64 { fn serialize(&self, output: &mut dyn Write) -> Result<()> { output.write_all(&self.to_be_bytes()).map_err(|err| { Error::SerializationError(format!("Failed to write serialize u64 to output: {err}")) })?; Ok(()) } fn deserialize(input: &mut dyn ReadSeek) -> Result { let mut buffer = [0u8; 8]; input.read_exact(&mut buffer).map_err(|_| { Error::InputTooSmall("Failed to read all bytes for u64 from the input".into()) })?; Ok(Self::from_be_bytes(buffer)) } fn size(&self) -> usize { 8 } } impl Serializable for i64 { fn serialize(&self, output: &mut dyn Write) -> Result<()> { output.write_all(&self.to_be_bytes()).map_err(|err| { Error::SerializationError(format!("Failed to write serialize i64 to output: {err}")) })?; Ok(()) } fn deserialize(input: &mut dyn ReadSeek) -> Result { let mut buffer = [0u8; 8]; input.read_exact(&mut buffer).map_err(|_| { Error::InputTooSmall("Failed to read all bytes for i64 from the input".into()) })?; Ok(Self::from_be_bytes(buffer)) } fn size(&self) -> usize { 8 } } impl Serializable for u128 { fn serialize(&self, output: &mut dyn Write) -> Result<()> { output.write_all(&self.to_be_bytes()).map_err(|err| { Error::SerializationError(format!("Failed to write serialize u128 to output: {err}")) })?; Ok(()) } fn deserialize(input: &mut dyn ReadSeek) -> Result { let mut buffer = [0u8; 16]; input.read_exact(&mut buffer).map_err(|_| { Error::InputTooSmall("Failed to read all bytes for u128 from the input".into()) })?; Ok(Self::from_be_bytes(buffer)) } fn size(&self) -> usize { 16 } } impl Serializable for i128 { fn serialize(&self, output: &mut dyn Write) -> Result<()> { output.write_all(&self.to_be_bytes()).map_err(|err| { Error::SerializationError(format!("Failed to write serialize i128 to output: {err}")) })?; Ok(()) } fn deserialize(input: &mut dyn ReadSeek) -> Result { let mut buffer = [0u8; 16]; input.read_exact(&mut buffer).map_err(|_| { Error::InputTooSmall("Failed to read all bytes for i128 from the input".into()) })?; Ok(Self::from_be_bytes(buffer)) } fn size(&self) -> usize { 16 } } #[cfg(test)] mod test { use super::*; // Hacky hack to refere to "crate" by its name use crate as androscalpel_serializer; #[test] fn serialize_u8() { assert_eq!(42u8.serialize_to_vec().unwrap(), vec![42u8]); } #[test] fn deserialize_u8() { assert_eq!(u8::deserialize_from_slice(&[42u8]).unwrap(), 42u8); } #[test] fn size_u8() { assert_eq!(42u8.size(), 1); } #[test] fn serialize_u16() { assert_eq!(0x1234u16.serialize_to_vec().unwrap(), vec![0x12u8, 0x34u8]); } #[test] fn deserialize_u16() { assert_eq!( u16::deserialize_from_slice(&[0x12u8, 0x34u8]).unwrap(), 0x1234u16 ); } #[test] fn size_u16() { assert_eq!(0x1234u16.size(), 2); } #[test] fn serialize_u32() { assert_eq!( 0x12345678u32.serialize_to_vec().unwrap(), vec![0x12u8, 0x34u8, 0x56u8, 0x78u8] ); } #[test] fn deserialize_u32() { assert_eq!( u32::deserialize_from_slice(&[0x12u8, 0x34u8, 0x56u8, 0x78u8]).unwrap(), 0x12345678u32 ); } #[test] fn size_u32() { assert_eq!(0x12345678u32.size(), 4); } #[test] fn serialize_u64() { assert_eq!( 0x123456789ABCDEF0u64.serialize_to_vec().unwrap(), vec![0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8] ); } #[test] fn deserialize_u64() { assert_eq!( u64::deserialize_from_slice(&[ 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8 ]) .unwrap(), 0x123456789ABCDEF0u64 ); } #[test] fn size_u64() { assert_eq!(0x123456789ABCDEF0u64.size(), 8); } #[test] fn serialize_u128() { assert_eq!( 0x123456789ABCDEF0123456789ABCDEF0u128 .serialize_to_vec() .unwrap(), vec![ 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8 ] ); } #[test] fn deserialize_u128() { assert_eq!( u128::deserialize_from_slice(&[ 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8 ]) .unwrap(), 0x123456789ABCDEF0123456789ABCDEF0u128 ); } #[test] fn size_u128() { assert_eq!(0x123456789ABCDEF0123456789ABCDEF0u128.size(), 16); } #[derive(Serializable, Debug, PartialEq, Eq)] struct NamedComposedTest { a: u8, b: u16, c: u32, d: u64, f: u128, } #[derive(Serializable, Debug, PartialEq, Eq)] struct UnamedComposedTest(u8, u16, u32, u64, u128); #[test] fn serialize_unnamed_derived() { let t = UnamedComposedTest( 42u8, 0x1234u16, 0x12345678u32, 0x123456789ABCDEF0u64, 0x123456789ABCDEF0123456789ABCDEF0u128, ); assert_eq!( t.serialize_to_vec().unwrap(), vec![ 42u8, 0x12u8, 0x34u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8 ] ); } #[test] fn deserialize_named_derived() { let t = UnamedComposedTest( 42u8, 0x1234u16, 0x12345678u32, 0x123456789ABCDEF0u64, 0x123456789ABCDEF0123456789ABCDEF0u128, ); let serialized = vec![ 42u8, 0x12u8, 0x34u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, ]; assert_eq!( UnamedComposedTest::deserialize_from_slice(&serialized).unwrap(), t ); } #[test] fn size_unnamed_derived() { let t = UnamedComposedTest( 42u8, 0x1234u16, 0x12345678u32, 0x123456789ABCDEF0u64, 0x123456789ABCDEF0123456789ABCDEF0u128, ); assert_eq!(t.size(), 1 + 2 + 4 + 8 + 16); } #[derive(Serializable, Debug, PartialEq, Eq)] struct NamedArrayComposedTest { a: [u8; 1], b: [u16; 2], c: [u32; 3], d: [u64; 4], e: [u128; 5], } #[derive(Serializable, Debug, PartialEq, Eq)] struct UnamedArrayComposedTest([u8; 1], [u16; 2], [u32; 3], [u64; 4], [u128; 5]); #[test] fn serialize_array_unamed_derived() { let t = UnamedArrayComposedTest( [42u8], [0x1234u16, 0x1234u16], [0x12345678u32, 0x12345678u32, 0x12345678u32], [ 0x123456789ABCDEF0u64, 0x123456789ABCDEF0u64, 0x123456789ABCDEF0u64, 0x123456789ABCDEF0u64, ], [ 0x123456789ABCDEF0123456789ABCDEF0u128, 0x123456789ABCDEF0123456789ABCDEF0u128, 0x123456789ABCDEF0123456789ABCDEF0u128, 0x123456789ABCDEF0123456789ABCDEF0u128, 0x123456789ABCDEF0123456789ABCDEF0u128, ], ); assert_eq!( t.serialize_to_vec().unwrap(), vec![ 42u8, 0x12u8, 0x34u8, 0x12u8, 0x34u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8 ] ); } #[test] fn deserialize_array_unamed_derived() { let t = UnamedArrayComposedTest( [42u8], [0x1234u16, 0x1234u16], [0x12345678u32, 0x12345678u32, 0x12345678u32], [ 0x123456789ABCDEF0u64, 0x123456789ABCDEF0u64, 0x123456789ABCDEF0u64, 0x123456789ABCDEF0u64, ], [ 0x123456789ABCDEF0123456789ABCDEF0u128, 0x123456789ABCDEF0123456789ABCDEF0u128, 0x123456789ABCDEF0123456789ABCDEF0u128, 0x123456789ABCDEF0123456789ABCDEF0u128, 0x123456789ABCDEF0123456789ABCDEF0u128, ], ); let serialized = vec![ 42u8, 0x12u8, 0x34u8, 0x12u8, 0x34u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, ]; assert_eq!( UnamedArrayComposedTest::deserialize_from_slice(&serialized).unwrap(), t ); } #[test] fn size_array_unamed_derived() { let t = UnamedArrayComposedTest( [42u8], [0x1234u16, 0x1234u16], [0x12345678u32, 0x12345678u32, 0x12345678u32], [ 0x123456789ABCDEF0u64, 0x123456789ABCDEF0u64, 0x123456789ABCDEF0u64, 0x123456789ABCDEF0u64, ], [ 0x123456789ABCDEF0123456789ABCDEF0u128, 0x123456789ABCDEF0123456789ABCDEF0u128, 0x123456789ABCDEF0123456789ABCDEF0u128, 0x123456789ABCDEF0123456789ABCDEF0u128, 0x123456789ABCDEF0123456789ABCDEF0u128, ], ); assert_eq!(t.size(), 1 + 2 * 2 + 4 * 3 + 8 * 4 + 16 * 5); } #[test] fn serialize_array_named_derived() { let t = NamedArrayComposedTest { a: [42u8], b: [0x1234u16, 0x1234u16], c: [0x12345678u32, 0x12345678u32, 0x12345678u32], d: [ 0x123456789ABCDEF0u64, 0x123456789ABCDEF0u64, 0x123456789ABCDEF0u64, 0x123456789ABCDEF0u64, ], e: [ 0x123456789ABCDEF0123456789ABCDEF0u128, 0x123456789ABCDEF0123456789ABCDEF0u128, 0x123456789ABCDEF0123456789ABCDEF0u128, 0x123456789ABCDEF0123456789ABCDEF0u128, 0x123456789ABCDEF0123456789ABCDEF0u128, ], }; assert_eq!( t.serialize_to_vec().unwrap(), vec![ 42u8, 0x12u8, 0x34u8, 0x12u8, 0x34u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8 ] ); } #[test] fn deserialize_array_named_derived() { let t = NamedArrayComposedTest { a: [42u8], b: [0x1234u16, 0x1234u16], c: [0x12345678u32, 0x12345678u32, 0x12345678u32], d: [ 0x123456789ABCDEF0u64, 0x123456789ABCDEF0u64, 0x123456789ABCDEF0u64, 0x123456789ABCDEF0u64, ], e: [ 0x123456789ABCDEF0123456789ABCDEF0u128, 0x123456789ABCDEF0123456789ABCDEF0u128, 0x123456789ABCDEF0123456789ABCDEF0u128, 0x123456789ABCDEF0123456789ABCDEF0u128, 0x123456789ABCDEF0123456789ABCDEF0u128, ], }; let serialized = vec![ 42u8, 0x12u8, 0x34u8, 0x12u8, 0x34u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, ]; assert_eq!( NamedArrayComposedTest::deserialize_from_slice(&serialized).unwrap(), t ); } #[test] fn size_array_named_derived() { let t = NamedArrayComposedTest { a: [42u8], b: [0x1234u16, 0x1234u16], c: [0x12345678u32, 0x12345678u32, 0x12345678u32], d: [ 0x123456789ABCDEF0u64, 0x123456789ABCDEF0u64, 0x123456789ABCDEF0u64, 0x123456789ABCDEF0u64, ], e: [ 0x123456789ABCDEF0123456789ABCDEF0u128, 0x123456789ABCDEF0123456789ABCDEF0u128, 0x123456789ABCDEF0123456789ABCDEF0u128, 0x123456789ABCDEF0123456789ABCDEF0u128, 0x123456789ABCDEF0123456789ABCDEF0u128, ], }; assert_eq!(t.size(), 1 + 2 * 2 + 4 * 3 + 8 * 4 + 16 * 5); } #[test] fn size_vec_serializable_until() { #[derive(Serializable, PartialEq, Eq)] struct UntilArray([u8; 3]); let v = vec![0u8, 1u8, 2u8, 3u8]; assert_eq!(v.size(UntilArray([0, 0, 0])), 7); assert_eq!(v.size(0u8), 5); } #[test] fn serialize_vec_serializable_until() { #[derive(Serializable, PartialEq, Eq)] struct UntilArray([u8; 3]); let v = vec![0u8, 1u8, 2u8, 3u8]; assert_eq!( v.serialize_to_vec(UntilArray([0, 0, 0])).unwrap(), vec![0u8, 1u8, 2u8, 3u8, 0u8, 0u8, 0u8] ); assert_eq!( v.serialize_to_vec(0u8).unwrap(), vec![0u8, 1u8, 2u8, 3u8, 0u8] ); } #[test] fn deserialize_vec_serializable_until() { #[derive(Serializable, PartialEq, Eq)] struct UntilArray([u8; 3]); let v1 = vec![0u8, 1u8, 2u8, 3u8]; let serialized_1 = &[0u8, 1u8, 2u8, 3u8, 0u8, 0u8, 0u8]; let serialized_2 = &[0u8, 1u8, 2u8, 3u8, 0u8]; assert_eq!( v1, Vec::::deserialize_from_slice(serialized_1, UntilArray([0, 0, 0])).unwrap() ); assert_eq!( Vec::::new(), Vec::::deserialize_from_slice(serialized_2, 0u8).unwrap() ); } #[derive(Serializable, PartialEq, Eq, Debug)] struct UntilArray2([u8; 2]); #[derive(Serializable, Debug, PartialEq, Eq)] struct SerializableUntilNamed { pr: u16, #[until(u8, UntilArray2, UntilArray2([0u8, 0u8]))] v: Vec, ps: u32, } #[test] fn size_named_serializable_until() { let v = SerializableUntilNamed { pr: 0, v: vec![1, 2, 3], ps: 0, }; assert_eq!(v.size(), 2 + 3 + 2 + 4); } #[test] fn serialize_named_serializable_until() { let v = SerializableUntilNamed { pr: 0, v: vec![1, 2, 3], ps: 0x80000000, }; assert_eq!( v.serialize_to_vec().unwrap(), vec![0, 0, 1, 2, 3, 0, 0, 0x80, 0, 0, 0], ); } #[test] fn deserialize_named_serializable_until() { let v = SerializableUntilNamed { pr: 0, v: vec![1, 2, 3], ps: 0x80000000, }; let s = &[0, 0, 1, 2, 3, 0, 0, 0x80, 0, 0, 0]; assert_eq!( v, SerializableUntilNamed::deserialize_from_slice(s).unwrap() ); } #[derive(Serializable, PartialEq, Eq, Debug)] #[prefix_type(u8)] enum TestEnum { #[prefix(0)] Zero, #[prefix(1)] One(u32), #[prefix(2)] Two { a: u16, b: u32 }, } #[test] fn size_enum() { assert_eq!(TestEnum::Zero.size(), 1); assert_eq!(TestEnum::One(42).size(), 5); assert_eq!(TestEnum::Two { a: 1, b: 2 }.size(), 7); } #[test] fn serialize_enum() { assert_eq!(TestEnum::Zero.serialize_to_vec().unwrap(), vec![0u8]); assert_eq!( TestEnum::One(42).serialize_to_vec().unwrap(), vec![1u8, 0u8, 0u8, 0u8, 42u8] ); assert_eq!( TestEnum::Two { a: 1, b: 2 }.serialize_to_vec().unwrap(), vec![2u8, 0u8, 1u8, 0u8, 0u8, 0u8, 2u8] ); } #[test] fn deserialize_enum() { assert_eq!( TestEnum::deserialize_from_slice(&[0u8]).unwrap(), TestEnum::Zero ); assert_eq!( TestEnum::deserialize_from_slice(&[1u8, 0u8, 0u8, 0u8, 42u8]).unwrap(), TestEnum::One(42) ); assert_eq!( TestEnum::deserialize_from_slice(&[2u8, 0u8, 1u8, 0u8, 0u8, 0u8, 2u8]).unwrap(), TestEnum::Two { a: 1, b: 2 } ); assert!(TestEnum::deserialize_from_slice(&[255u8]).is_err()); } #[derive(Serializable, PartialEq, Debug)] struct TestPrefixSuffix { #[prefix([0x42])] #[suffix([0x66, 0x66])] a: u32, } #[test] fn deserialize_prefix_suffix() { assert_eq!( TestPrefixSuffix::deserialize_from_slice(&[0x42, 0, 1, 2, 3, 0x66, 0x66]).unwrap(), TestPrefixSuffix { a: 0x00010203 } ); } #[test] fn serialize_prefix_suffix() { assert_eq!( TestPrefixSuffix { a: 0x00010203 } .serialize_to_vec() .unwrap(), vec![0x42, 0, 1, 2, 3, 0x66, 0x66] ); } }