1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
use std::io::{Read, Write};
use crate::error::{DecodeError, EncodeError};
use crate::ll::marker::Marker;
use byteorder::{WriteBytesExt, ReadBytesExt};
use packable_struct::PackableStruct;
pub mod packable_struct;
pub mod struct_sum;
pub mod generic_struct;
pub fn encode_struct<S: PackableStruct, T: Write>(value: &S, tag_byte: u8, writer: &mut T) -> Result<usize, EncodeError> {
Marker::Structure(S::FIELDS).encode(writer)?;
writer.write_u8(tag_byte)?;
Ok(2 + value.write_structure_body(writer)?)
}
pub fn decode_struct<S: PackableStruct, T: Read>(tag_byte: u8, reader: &mut T) -> Result<S, DecodeError> {
let marker = Marker::decode(reader)?;
match marker {
Marker::Structure(u) => {
if u != S::FIELDS {
Err(DecodeError::UnexpectedNumberOfFields(S::FIELDS, u))
} else {
let tag = reader.read_u8()?;
if tag != tag_byte {
Err(DecodeError::UnexpectedTagByte(tag))
} else {
S::read_structure_body(reader)
}
}
},
_ => Err(DecodeError::UnexpectedMarker(marker))
}
}
#[cfg(test)]
pub mod test {
use crate::{PackableStruct, encode_struct, decode_struct};
use std::fmt::Debug;
pub fn pack_unpack_struct_test<T: PackableStruct + PartialEq + Debug>(value: &T, expected_size: usize, tag_byte: u8) {
let mut buffer = Vec::new();
let written = encode_struct(value, tag_byte, &mut buffer).unwrap();
assert_eq!(expected_size, written);
let res: T = decode_struct(tag_byte, &mut buffer.as_slice()).unwrap();
assert_eq!(value, &res);
}
}