plabble_codec/codec/common/
slot_body.rs1use std::collections::HashMap;
2
3use itertools::Itertools;
4
5use crate::abstractions::{Serializable, SerializationError, SerializationInfo};
6
7use super::{assert_len, dyn_int};
8
9pub type SlotBody = HashMap<u16, Vec<u8>>;
11
12impl Serializable for SlotBody {
13 fn size(&self) -> usize {
15 self.iter()
16 .map(|s| 2 + s.1.len() + dyn_int::encoded_size(s.1.len() as u128))
17 .sum::<usize>()
18 }
19
20 fn get_bytes(&self) -> Vec<u8> {
22 let mut buff = Vec::new();
23 for (idx, data) in self.iter().sorted() {
24 buff.extend_from_slice(&idx.to_be_bytes());
25 buff.append(&mut dyn_int::encode(data.len() as u128));
26 buff.extend_from_slice(data);
27 }
28 buff
29 }
30
31 fn from_bytes(data: &[u8], _: Option<SerializationInfo>) -> Result<Self, SerializationError>
33 where
34 Self: Sized,
35 {
36 let mut slots: HashMap<u16, Vec<u8>> = HashMap::new();
37 let mut bytes_read = 0;
38 while bytes_read != data.len() {
39 assert_len(data, bytes_read + 3)?;
40 let mut idx = [0u8; 2];
41 idx.copy_from_slice(&data[bytes_read..(bytes_read + 2)]);
42 let idx = u16::from_be_bytes(idx);
43 bytes_read += 2;
44 let (data_len, read) = dyn_int::read_from_slice(&data[bytes_read..])?;
45 bytes_read += read;
46 assert_len(data, bytes_read + data_len as usize)?;
47 let data = data[bytes_read..(bytes_read + data_len as usize)].to_vec();
48 bytes_read += data_len as usize;
49 let _ = slots.insert(idx, data);
50 }
51
52 Ok(slots)
53 }
54}
55
56#[cfg(test)]
57mod test {
58 use crate::abstractions::Serializable;
59
60 use super::SlotBody;
61
62 #[test]
63 fn can_serialize_slot_body() {
64 let mut slots = SlotBody::new();
65 slots.insert(0, vec![0u8; 10]);
66 slots.insert(5, vec![1u8; 5]);
67
68 let bytes = slots.get_bytes();
69 assert_eq!(
70 vec![0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 1, 1, 1, 1, 1],
71 bytes
72 );
73 }
74
75 #[test]
76 fn can_deserialize_slot_body() {
77 let bytes = vec![0, 7, 3, 1, 2, 3, 0, 12, 5, 1, 1, 1, 1, 1];
78 let slots = SlotBody::from_bytes(&bytes, None).unwrap();
79 assert_eq!(&vec![1, 1, 1, 1, 1], slots.get(&12).unwrap());
80 assert_eq!(&vec![1, 2, 3], slots.get(&7).unwrap());
81 }
82}