binary_codec/
dynamics.rs

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]; // 7
152        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); // first 4 bits
162        let result = read_small_dynamic_unsigned(&bytes, &mut config, bit_count).unwrap();
163        assert_eq!(result, 5); // last 4 bits
164    }
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; // 8, out of bounds for 3 bits
172        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; // out of bounds for 3 bits signed
182        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}