put current androscalpel_serializer to a core module
This commit is contained in:
parent
ab1d6f4f8c
commit
1a9030267c
2 changed files with 851 additions and 845 deletions
849
androscalpel_serializer/src/core.rs
Normal file
849
androscalpel_serializer/src/core.rs
Normal file
|
|
@ -0,0 +1,849 @@
|
||||||
|
/// 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::*;
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
pub enum Error {
|
||||||
|
InputTooSmall(String), // TODO: find a better name
|
||||||
|
SerializeationError(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Result<T> = core::result::Result<T, Error>;
|
||||||
|
|
||||||
|
pub trait ReadSeek: Read + Seek {}
|
||||||
|
impl<T: Read + Seek> 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::SerializeationError(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<Self>
|
||||||
|
where
|
||||||
|
Self: Sized;
|
||||||
|
fn size(&self) -> usize;
|
||||||
|
|
||||||
|
fn serialize_to_vec(&self) -> Result<Vec<u8>> {
|
||||||
|
let mut output = Cursor::new(Vec::<u8>::new());
|
||||||
|
self.serialize(&mut output)?;
|
||||||
|
Ok(output.into_inner())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize_from_slice(input: &[u8]) -> Result<Self>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
let mut buffer = Cursor::new(input);
|
||||||
|
Self::deserialize(&mut buffer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait SerializableUntil<D: Serializable, U: Serializable + Eq> {
|
||||||
|
fn serialize(&self, output: &mut dyn Write, end_val: U) -> Result<()>;
|
||||||
|
fn deserialize(input: &mut dyn ReadSeek, end_val: U) -> Result<Self>
|
||||||
|
where
|
||||||
|
Self: Sized;
|
||||||
|
fn size(&self, end_val: U) -> usize;
|
||||||
|
fn serialize_to_vec(&self, end_val: U) -> Result<Vec<u8>> {
|
||||||
|
let mut output = Cursor::new(Vec::<u8>::new());
|
||||||
|
self.serialize(&mut output, end_val)?;
|
||||||
|
Ok(output.into_inner())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize_from_slice(input: &[u8], end_val: U) -> Result<Self>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
let mut buffer = Cursor::new(input);
|
||||||
|
Self::deserialize(&mut buffer, end_val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D: Serializable, U: Serializable + Eq> SerializableUntil<D, U> for Vec<D> {
|
||||||
|
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<Self>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
let mut data = Self::new();
|
||||||
|
loop {
|
||||||
|
let pos = input.stream_position().map_err(|err| {
|
||||||
|
Error::SerializeationError(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::SerializeationError(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::<usize>() + 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::SerializeationError(format!("Failed to write serialize u8 to output: {err}"))
|
||||||
|
})?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
||||||
|
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::SerializeationError(format!("Failed to write serialize i8 to output: {err}"))
|
||||||
|
})?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
||||||
|
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::SerializeationError(format!("Failed to write serialize u16 to output: {err}"))
|
||||||
|
})?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
||||||
|
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::SerializeationError(format!("Failed to write serialize i16 to output: {err}"))
|
||||||
|
})?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
||||||
|
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::SerializeationError(format!("Failed to write serialize u32 to output: {err}"))
|
||||||
|
})?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
||||||
|
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::SerializeationError(format!("Failed to write serialize i32 to output: {err}"))
|
||||||
|
})?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
||||||
|
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::SerializeationError(format!("Failed to write serialize u64 to output: {err}"))
|
||||||
|
})?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
||||||
|
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::SerializeationError(format!("Failed to write serialize i64 to output: {err}"))
|
||||||
|
})?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
||||||
|
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::SerializeationError(format!("Failed to write serialize u128 to output: {err}"))
|
||||||
|
})?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
||||||
|
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::SerializeationError(format!("Failed to write serialize i128 to output: {err}"))
|
||||||
|
})?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
||||||
|
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::<u8>::deserialize_from_slice(serialized_1, UntilArray([0, 0, 0])).unwrap()
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
Vec::<u8>::new(),
|
||||||
|
Vec::<u8>::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<u8>,
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,846 +1,3 @@
|
||||||
use std::io::{Cursor, Read, Seek, SeekFrom, Write};
|
pub mod core;
|
||||||
|
|
||||||
pub use androscalpel_serializer_derive::*;
|
pub use crate::core::*;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
|
||||||
pub enum Error {
|
|
||||||
InputTooSmall(String), // TODO: find a better name
|
|
||||||
SerializeationError(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type Result<T> = core::result::Result<T, Error>;
|
|
||||||
|
|
||||||
pub trait ReadSeek: Read + Seek {}
|
|
||||||
impl<T: Read + Seek> 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::SerializeationError(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<Self>
|
|
||||||
where
|
|
||||||
Self: Sized;
|
|
||||||
fn size(&self) -> usize;
|
|
||||||
|
|
||||||
fn serialize_to_vec(&self) -> Result<Vec<u8>> {
|
|
||||||
let mut output = Cursor::new(Vec::<u8>::new());
|
|
||||||
self.serialize(&mut output)?;
|
|
||||||
Ok(output.into_inner())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_from_slice(input: &[u8]) -> Result<Self>
|
|
||||||
where
|
|
||||||
Self: Sized,
|
|
||||||
{
|
|
||||||
let mut buffer = Cursor::new(input);
|
|
||||||
Self::deserialize(&mut buffer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait SerializableUntil<D: Serializable, U: Serializable + Eq> {
|
|
||||||
fn serialize(&self, output: &mut dyn Write, end_val: U) -> Result<()>;
|
|
||||||
fn deserialize(input: &mut dyn ReadSeek, end_val: U) -> Result<Self>
|
|
||||||
where
|
|
||||||
Self: Sized;
|
|
||||||
fn size(&self, end_val: U) -> usize;
|
|
||||||
fn serialize_to_vec(&self, end_val: U) -> Result<Vec<u8>> {
|
|
||||||
let mut output = Cursor::new(Vec::<u8>::new());
|
|
||||||
self.serialize(&mut output, end_val)?;
|
|
||||||
Ok(output.into_inner())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_from_slice(input: &[u8], end_val: U) -> Result<Self>
|
|
||||||
where
|
|
||||||
Self: Sized,
|
|
||||||
{
|
|
||||||
let mut buffer = Cursor::new(input);
|
|
||||||
Self::deserialize(&mut buffer, end_val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<D: Serializable, U: Serializable + Eq> SerializableUntil<D, U> for Vec<D> {
|
|
||||||
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<Self>
|
|
||||||
where
|
|
||||||
Self: Sized,
|
|
||||||
{
|
|
||||||
let mut data = Self::new();
|
|
||||||
loop {
|
|
||||||
let pos = input.stream_position().map_err(|err| {
|
|
||||||
Error::SerializeationError(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::SerializeationError(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::<usize>() + 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::SerializeationError(format!("Failed to write serialize u8 to output: {err}"))
|
|
||||||
})?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
|
||||||
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::SerializeationError(format!("Failed to write serialize i8 to output: {err}"))
|
|
||||||
})?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
|
||||||
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::SerializeationError(format!("Failed to write serialize u16 to output: {err}"))
|
|
||||||
})?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
|
||||||
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::SerializeationError(format!("Failed to write serialize i16 to output: {err}"))
|
|
||||||
})?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
|
||||||
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::SerializeationError(format!("Failed to write serialize u32 to output: {err}"))
|
|
||||||
})?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
|
||||||
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::SerializeationError(format!("Failed to write serialize i32 to output: {err}"))
|
|
||||||
})?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
|
||||||
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::SerializeationError(format!("Failed to write serialize u64 to output: {err}"))
|
|
||||||
})?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
|
||||||
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::SerializeationError(format!("Failed to write serialize i64 to output: {err}"))
|
|
||||||
})?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
|
||||||
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::SerializeationError(format!("Failed to write serialize u128 to output: {err}"))
|
|
||||||
})?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
|
||||||
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::SerializeationError(format!("Failed to write serialize i128 to output: {err}"))
|
|
||||||
})?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
|
||||||
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::<u8>::deserialize_from_slice(serialized_1, UntilArray([0, 0, 0])).unwrap()
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
Vec::<u8>::new(),
|
|
||||||
Vec::<u8>::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<u8>,
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue