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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
mod de;
mod error;
mod ser;
mod varint;
pub use crate::error::Error;
use crate::de::Deserializer;
use crate::ser::Serializer;
use serde::de::DeserializeOwned;
use serde::Serialize;
use std::io::Read;
pub type Result<T> = std::result::Result<T, Error>;
const HEADER: &[u8] = b"\x01\x11\x01\x01\x01\x01\x02\x01\x01";
pub fn to_bytes<T>(object: &T) -> Result<Vec<u8>>
where
T: Serialize,
{
let mut buffer = Vec::new();
buffer.extend_from_slice(HEADER);
let mut serializer = Serializer::new_root(&mut buffer);
object.serialize(&mut serializer)?;
Ok(buffer)
}
pub fn from_bytes<T, B>(bytes: B) -> Result<T>
where
T: DeserializeOwned,
B: AsRef<[u8]>,
{
let mut bytes = bytes.as_ref();
let mut header = [0u8; 9];
bytes.read_exact(&mut header)?;
let has_header = header == HEADER;
if !has_header {
return Err(Error::missing_header_bytes());
}
let mut deserializer = Deserializer::new(&mut bytes);
T::deserialize(&mut deserializer)
}
const MARKER_I64: u8 = 1;
const MARKER_I32: u8 = 2;
const MARKER_I16: u8 = 3;
const MARKER_I8: u8 = 4;
const MARKER_U64: u8 = 5;
const MARKER_U32: u8 = 6;
const MARKER_U16: u8 = 7;
const MARKER_U8: u8 = 8;
const MARKER_F64: u8 = 9;
const MARKER_STRING: u8 = 10;
const MARKER_BOOL: u8 = 11;
const MARKER_STRUCT: u8 = 12;
const MARKER_ARRAY_ELEMENT: u8 = 0x80;
#[cfg(test)]
mod tests {
use super::*;
#[derive(Serialize)]
struct RootStruct {
foo: u64,
bars: Vec<Bar>,
}
#[derive(Serialize)]
struct Bar {
number: u64,
}
#[test]
fn nested_struct_has_struct_marker() {
let bytes = to_bytes(&RootStruct {
foo: 100,
bars: vec![Bar { number: 1 }, Bar { number: 2 }],
})
.unwrap();
let payload = &bytes[9..];
assert_eq!(&payload, b"\x08\x03foo\x05\x64\x00\x00\x00\x00\x00\x00\x00\x04bars\x8c\x08\x04\x06number\x05\x01\x00\x00\x00\x00\x00\x00\x00\x04\x06number\x05\x02\x00\x00\x00\x00\x00\x00\x00")
}
#[test]
fn root_element_must_be_struct() {
to_bytes(&1u64).unwrap_err();
to_bytes(&[1u64]).unwrap_err();
to_bytes(&true).unwrap_err();
}
}