summavy_common/
serialize.rs

1use std::io::{Read, Write};
2use std::{fmt, io};
3
4use byteorder::{ReadBytesExt, WriteBytesExt};
5
6use crate::{Endianness, VInt};
7
8/// Trait for a simple binary serialization.
9pub trait BinarySerializable: fmt::Debug + Sized {
10    /// Serialize
11    fn serialize<W: Write>(&self, writer: &mut W) -> io::Result<()>;
12    /// Deserialize
13    fn deserialize<R: Read>(reader: &mut R) -> io::Result<Self>;
14}
15
16pub trait DeserializeFrom<T: BinarySerializable> {
17    fn deserialize(&mut self) -> io::Result<T>;
18}
19
20/// Implement deserialize from &[u8] for all types which implement BinarySerializable.
21///
22/// TryFrom would actually be preferable, but not possible because of the orphan
23/// rules (not completely sure if this could be resolved)
24impl<T: BinarySerializable> DeserializeFrom<T> for &[u8] {
25    fn deserialize(&mut self) -> io::Result<T> {
26        T::deserialize(self)
27    }
28}
29
30/// `FixedSize` marks a `BinarySerializable` as
31/// always serializing to the same size.
32pub trait FixedSize: BinarySerializable {
33    const SIZE_IN_BYTES: usize;
34}
35
36impl BinarySerializable for () {
37    fn serialize<W: Write>(&self, _: &mut W) -> io::Result<()> {
38        Ok(())
39    }
40    fn deserialize<R: Read>(_: &mut R) -> io::Result<Self> {
41        Ok(())
42    }
43}
44
45impl FixedSize for () {
46    const SIZE_IN_BYTES: usize = 0;
47}
48
49impl<T: BinarySerializable> BinarySerializable for Vec<T> {
50    fn serialize<W: Write>(&self, writer: &mut W) -> io::Result<()> {
51        VInt(self.len() as u64).serialize(writer)?;
52        for it in self {
53            it.serialize(writer)?;
54        }
55        Ok(())
56    }
57    fn deserialize<R: Read>(reader: &mut R) -> io::Result<Vec<T>> {
58        let num_items = VInt::deserialize(reader)?.val();
59        let mut items: Vec<T> = Vec::with_capacity(num_items as usize);
60        for _ in 0..num_items {
61            let item = T::deserialize(reader)?;
62            items.push(item);
63        }
64        Ok(items)
65    }
66}
67
68impl<Left: BinarySerializable, Right: BinarySerializable> BinarySerializable for (Left, Right) {
69    fn serialize<W: Write>(&self, write: &mut W) -> io::Result<()> {
70        self.0.serialize(write)?;
71        self.1.serialize(write)
72    }
73    fn deserialize<R: Read>(reader: &mut R) -> io::Result<Self> {
74        Ok((Left::deserialize(reader)?, Right::deserialize(reader)?))
75    }
76}
77impl<Left: BinarySerializable + FixedSize, Right: BinarySerializable + FixedSize> FixedSize
78    for (Left, Right)
79{
80    const SIZE_IN_BYTES: usize = Left::SIZE_IN_BYTES + Right::SIZE_IN_BYTES;
81}
82
83impl BinarySerializable for u32 {
84    fn serialize<W: Write>(&self, writer: &mut W) -> io::Result<()> {
85        writer.write_u32::<Endianness>(*self)
86    }
87
88    fn deserialize<R: Read>(reader: &mut R) -> io::Result<u32> {
89        reader.read_u32::<Endianness>()
90    }
91}
92
93impl FixedSize for u32 {
94    const SIZE_IN_BYTES: usize = 4;
95}
96
97impl BinarySerializable for u16 {
98    fn serialize<W: Write>(&self, writer: &mut W) -> io::Result<()> {
99        writer.write_u16::<Endianness>(*self)
100    }
101
102    fn deserialize<R: Read>(reader: &mut R) -> io::Result<u16> {
103        reader.read_u16::<Endianness>()
104    }
105}
106
107impl FixedSize for u16 {
108    const SIZE_IN_BYTES: usize = 2;
109}
110
111impl BinarySerializable for u64 {
112    fn serialize<W: Write>(&self, writer: &mut W) -> io::Result<()> {
113        writer.write_u64::<Endianness>(*self)
114    }
115    fn deserialize<R: Read>(reader: &mut R) -> io::Result<Self> {
116        reader.read_u64::<Endianness>()
117    }
118}
119
120impl FixedSize for u64 {
121    const SIZE_IN_BYTES: usize = 8;
122}
123
124impl BinarySerializable for u128 {
125    fn serialize<W: Write>(&self, writer: &mut W) -> io::Result<()> {
126        writer.write_u128::<Endianness>(*self)
127    }
128    fn deserialize<R: Read>(reader: &mut R) -> io::Result<Self> {
129        reader.read_u128::<Endianness>()
130    }
131}
132
133impl FixedSize for u128 {
134    const SIZE_IN_BYTES: usize = 16;
135}
136
137impl BinarySerializable for f32 {
138    fn serialize<W: Write>(&self, writer: &mut W) -> io::Result<()> {
139        writer.write_f32::<Endianness>(*self)
140    }
141    fn deserialize<R: Read>(reader: &mut R) -> io::Result<Self> {
142        reader.read_f32::<Endianness>()
143    }
144}
145
146impl FixedSize for f32 {
147    const SIZE_IN_BYTES: usize = 4;
148}
149
150impl BinarySerializable for i64 {
151    fn serialize<W: Write>(&self, writer: &mut W) -> io::Result<()> {
152        writer.write_i64::<Endianness>(*self)
153    }
154    fn deserialize<R: Read>(reader: &mut R) -> io::Result<Self> {
155        reader.read_i64::<Endianness>()
156    }
157}
158
159impl FixedSize for i64 {
160    const SIZE_IN_BYTES: usize = 8;
161}
162
163impl BinarySerializable for f64 {
164    fn serialize<W: Write>(&self, writer: &mut W) -> io::Result<()> {
165        writer.write_f64::<Endianness>(*self)
166    }
167    fn deserialize<R: Read>(reader: &mut R) -> io::Result<Self> {
168        reader.read_f64::<Endianness>()
169    }
170}
171
172impl FixedSize for f64 {
173    const SIZE_IN_BYTES: usize = 8;
174}
175
176impl BinarySerializable for u8 {
177    fn serialize<W: Write>(&self, writer: &mut W) -> io::Result<()> {
178        writer.write_u8(*self)
179    }
180    fn deserialize<R: Read>(reader: &mut R) -> io::Result<u8> {
181        reader.read_u8()
182    }
183}
184
185impl FixedSize for u8 {
186    const SIZE_IN_BYTES: usize = 1;
187}
188
189impl BinarySerializable for bool {
190    fn serialize<W: Write>(&self, writer: &mut W) -> io::Result<()> {
191        writer.write_u8(u8::from(*self))
192    }
193    fn deserialize<R: Read>(reader: &mut R) -> io::Result<bool> {
194        let val = reader.read_u8()?;
195        match val {
196            0 => Ok(false),
197            1 => Ok(true),
198            _ => Err(io::Error::new(
199                io::ErrorKind::InvalidData,
200                "invalid bool value on deserialization, data corrupted",
201            )),
202        }
203    }
204}
205
206impl FixedSize for bool {
207    const SIZE_IN_BYTES: usize = 1;
208}
209
210impl BinarySerializable for String {
211    fn serialize<W: Write>(&self, writer: &mut W) -> io::Result<()> {
212        let data: &[u8] = self.as_bytes();
213        VInt(data.len() as u64).serialize(writer)?;
214        writer.write_all(data)
215    }
216
217    fn deserialize<R: Read>(reader: &mut R) -> io::Result<String> {
218        let string_length = VInt::deserialize(reader)?.val() as usize;
219        let mut result = String::with_capacity(string_length);
220        reader
221            .take(string_length as u64)
222            .read_to_string(&mut result)?;
223        Ok(result)
224    }
225}
226
227#[cfg(test)]
228pub mod test {
229
230    use super::{VInt, *};
231    use crate::serialize::BinarySerializable;
232    pub fn fixed_size_test<O: BinarySerializable + FixedSize + Default>() {
233        let mut buffer = Vec::new();
234        O::default().serialize(&mut buffer).unwrap();
235        assert_eq!(buffer.len(), O::SIZE_IN_BYTES);
236    }
237
238    fn serialize_test<T: BinarySerializable + Eq>(v: T) -> usize {
239        let mut buffer: Vec<u8> = Vec::new();
240        v.serialize(&mut buffer).unwrap();
241        let num_bytes = buffer.len();
242        let mut cursor = &buffer[..];
243        let deser = T::deserialize(&mut cursor).unwrap();
244        assert_eq!(deser, v);
245        num_bytes
246    }
247
248    #[test]
249    fn test_serialize_u8() {
250        fixed_size_test::<u8>();
251    }
252
253    #[test]
254    fn test_serialize_u32() {
255        fixed_size_test::<u32>();
256        assert_eq!(4, serialize_test(3u32));
257        assert_eq!(4, serialize_test(5u32));
258        assert_eq!(4, serialize_test(u32::MAX));
259    }
260
261    #[test]
262    fn test_serialize_i64() {
263        fixed_size_test::<i64>();
264    }
265
266    #[test]
267    fn test_serialize_f64() {
268        fixed_size_test::<f64>();
269    }
270
271    #[test]
272    fn test_serialize_u64() {
273        fixed_size_test::<u64>();
274    }
275
276    #[test]
277    fn test_serialize_bool() {
278        fixed_size_test::<bool>();
279    }
280
281    #[test]
282    fn test_serialize_string() {
283        assert_eq!(serialize_test(String::from("")), 1);
284        assert_eq!(serialize_test(String::from("ぽよぽよ")), 1 + 3 * 4);
285        assert_eq!(serialize_test(String::from("富士さん見える。")), 1 + 3 * 8);
286    }
287
288    #[test]
289    fn test_serialize_vec() {
290        assert_eq!(serialize_test(Vec::<u8>::new()), 1);
291        assert_eq!(serialize_test(vec![1u32, 3u32]), 1 + 4 * 2);
292    }
293
294    #[test]
295    fn test_serialize_vint() {
296        for i in 0..10_000 {
297            serialize_test(VInt(i as u64));
298        }
299        assert_eq!(serialize_test(VInt(7u64)), 1);
300        assert_eq!(serialize_test(VInt(127u64)), 1);
301        assert_eq!(serialize_test(VInt(128u64)), 2);
302        assert_eq!(serialize_test(VInt(129u64)), 2);
303        assert_eq!(serialize_test(VInt(1234u64)), 2);
304        assert_eq!(serialize_test(VInt(16_383u64)), 2);
305        assert_eq!(serialize_test(VInt(16_384u64)), 3);
306        assert_eq!(serialize_test(VInt(u64::MAX)), 10);
307    }
308}