1use crate::{DeserializationError, SerializationError, SerializerConfig, fixed_int::ZigZag};
2
3pub fn read_small_dynamic_unsigned<T: Clone>(
4 bytes: &[u8],
5 config: &mut SerializerConfig<T>,
6 bit_count: u8,
7) -> Result<u8, DeserializationError> {
8 read_small_dynamic(bytes, config, bit_count)
9}
10
11pub fn read_small_dynamic_signed<T: Clone>(
12 bytes: &[u8],
13 config: &mut SerializerConfig<T>,
14 bit_count: u8,
15) -> Result<i8, DeserializationError> {
16 let val = read_small_dynamic(bytes, config, bit_count)?;
17 Ok(ZigZag::to_signed(val))
18}
19
20pub fn write_small_dynamic_unsigned<T: Clone>(
21 val: u8,
22 bytes: &mut Vec<u8>,
23 config: &mut SerializerConfig<T>,
24 bit_count: u8,
25) -> Result<(), SerializationError> {
26 let max = (1u8 << bit_count) - 1;
27
28 if val > max {
29 return Err(SerializationError::ValueOutOfBounds(
30 val as i32, 0, max as i32,
31 ));
32 }
33
34 write_small_dynamic(val, bytes, config, bit_count)
35}
36
37pub fn write_small_dynamic_signed<T: Clone>(
38 val: i8,
39 bytes: &mut Vec<u8>,
40 config: &mut SerializerConfig<T>,
41 bit_count: u8,
42) -> Result<(), SerializationError> {
43 let min = -(1i8 << (bit_count - 1));
44 let max = (1i8 << (bit_count - 1)) - 1;
45
46 if val < min || val > max {
47 return Err(SerializationError::ValueOutOfBounds(
48 val as i32, min as i32, max as i32,
49 ));
50 }
51
52 write_small_dynamic(val.to_unsigned(), bytes, config, bit_count)
53}
54
55pub fn write_bool<T: Clone>(
56 val: bool,
57 bytes: &mut Vec<u8>,
58 config: &mut SerializerConfig<T>,
59) -> Result<(), SerializationError> {
60 let val_u8 = if val { 1 } else { 0 };
61 write_small_dynamic(val_u8, bytes, config, 1)
62}
63
64pub fn read_bool<T: Clone>(
65 bytes: &[u8],
66 config: &mut SerializerConfig<T>,
67) -> Result<bool, DeserializationError> {
68 let val = read_small_dynamic(bytes, config, 1)?;
69 Ok(val != 0)
70}
71
72fn create_mask(bits: &u8, bit_count: u8) -> u8 {
73 let mask = (1u8 << bit_count) - 1u8;
74 return mask << *bits;
75}
76
77fn read_small_dynamic<T: Clone>(
78 bytes: &[u8],
79 config: &mut SerializerConfig<T>,
80 bit_count: u8,
81) -> Result<u8, DeserializationError> {
82 if config.bits == 8 || config.bits + bit_count > 8 {
83 config.bits = 0;
84 config.pos += 1;
85 }
86
87 let mask = create_mask(&config.bits, bit_count);
88
89 let val = bytes[config.pos];
90 let result = (val & mask) >> config.bits;
91 config.bits += bit_count;
92
93 Ok(result)
94}
95
96fn write_small_dynamic<T: Clone>(
97 val: u8,
98 bytes: &mut Vec<u8>,
99 config: &mut SerializerConfig<T>,
100 bit_count: u8,
101) -> Result<(), SerializationError> {
102 if config.bits == 0 || config.bits + bit_count > 8 {
103 config.bits = 0;
104
105 if bytes.len() > 0 {
106 config.pos += 1;
107 }
108
109 bytes.push(0u8);
110 }
111
112 let mask = create_mask(&config.bits, bit_count);
113
114 bytes[config.pos] &= !mask;
115 bytes[config.pos] |= (val << config.bits) & mask;
116
117 config.bits += bit_count;
118 Ok(())
119}
120
121#[cfg(test)]
122mod tests {
123 use super::*;
124
125 #[test]
126 fn test_write_read_small_dynamic_unsigned() {
127 let mut bytes = Vec::new();
128 let mut config = SerializerConfig::<()>::new(None);
129 let bit_count = 4;
130 let val: u8 = 0b1010;
131 write_small_dynamic_unsigned(val, &mut bytes, &mut config, bit_count).unwrap();
132 let mut config = SerializerConfig::<()>::new(None);
133 let result = read_small_dynamic_unsigned(&bytes, &mut config, bit_count).unwrap();
134 assert_eq!(result, val);
135 }
136
137 #[test]
138 fn test_write_read_small_dynamic_signed() {
139 let mut bytes = Vec::new();
140 let mut config = SerializerConfig::<()>::new(None);
141 let bit_count = 4;
142 let val: i8 = -3;
143 write_small_dynamic_signed(val, &mut bytes, &mut config, bit_count).unwrap();
144 let mut config = SerializerConfig::<()>::new(None);
145 let result = read_small_dynamic_signed(&bytes, &mut config, bit_count).unwrap();
146 assert_eq!(result, val);
147 }
148
149 #[test]
150 fn test_write_read_small_dynamic_unsigned_existing_byte() {
151 let mut bytes = vec![0b0000_0111]; let mut config = SerializerConfig::<()>::new(None);
153 config.pos = 0;
154 config.bits = 4;
155 let bit_count = 4;
156 let val: u8 = 5;
157 write_small_dynamic_unsigned(val, &mut bytes, &mut config, bit_count).unwrap();
158 assert_eq!(bytes, vec![0b0101_0111]);
159 let mut config = SerializerConfig::<()>::new(None);
160 let result = read_small_dynamic_unsigned(&bytes, &mut config, bit_count).unwrap();
161 assert_eq!(result, 7); let result = read_small_dynamic_unsigned(&bytes, &mut config, bit_count).unwrap();
163 assert_eq!(result, 5); }
165
166 #[test]
167 fn test_write_small_dynamic_unsigned_out_of_bounds() {
168 let mut bytes = Vec::new();
169 let mut config = SerializerConfig::<()>::new(None);
170 let bit_count = 3;
171 let val: u8 = 0b1000; let result = write_small_dynamic_unsigned(val, &mut bytes, &mut config, bit_count);
173 assert!(result.is_err());
174 }
175
176 #[test]
177 fn test_write_small_dynamic_signed_out_of_bounds() {
178 let mut bytes = Vec::new();
179 let mut config = SerializerConfig::<()>::new(None);
180 let bit_count = 3;
181 let val: i8 = 5; let result = write_small_dynamic_signed(val, &mut bytes, &mut config, bit_count);
183 assert!(result.is_err());
184 }
185
186 #[test]
187 fn test_write_read_bool_true() {
188 let mut bytes = Vec::new();
189 let mut config = SerializerConfig::<()>::new(None);
190 write_bool(true, &mut bytes, &mut config).unwrap();
191 let mut config = SerializerConfig::<()>::new(None);
192 let result = read_bool(&bytes, &mut config).unwrap();
193 assert_eq!(result, true);
194 }
195
196 #[test]
197 fn test_write_read_bool_false() {
198 let mut bytes = Vec::new();
199 let mut config = SerializerConfig::<()>::new(None);
200 write_bool(false, &mut bytes, &mut config).unwrap();
201 let mut config = SerializerConfig::<()>::new(None);
202 let result = read_bool(&bytes, &mut config).unwrap();
203 assert_eq!(result, false);
204 }
205
206 #[test]
207 fn test_create_mask_3() {
208 let bits = 2u8;
209 let bit_count = 3u8;
210 let mask = create_mask(&bits, bit_count);
211 assert_eq!(mask, 0b0001_1100);
212 }
213
214 #[test]
215 fn test_create_mask_2() {
216 let bits = 3u8;
217 let bit_count = 2u8;
218 let mask = create_mask(&bits, bit_count);
219 assert_eq!(mask, 0b0001_1000);
220 }
221}