naia_serde/
integer.rs

1use crate::{
2    bit_reader::BitReader, bit_writer::BitWrite, error::SerdeErr, serde::Serde, ConstBitLength,
3};
4
5pub type UnsignedInteger<const BITS: u8> = SerdeInteger<false, false, BITS>;
6pub type SignedInteger<const BITS: u8> = SerdeInteger<true, false, BITS>;
7pub type UnsignedVariableInteger<const BITS: u8> = SerdeInteger<false, true, BITS>;
8pub type SignedVariableInteger<const BITS: u8> = SerdeInteger<true, true, BITS>;
9
10#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
11pub struct SerdeInteger<const SIGNED: bool, const VARIABLE: bool, const BITS: u8> {
12    inner: i128,
13}
14
15impl<const SIGNED: bool, const VARIABLE: bool, const BITS: u8>
16    SerdeInteger<SIGNED, VARIABLE, BITS>
17{
18    pub fn get(&self) -> i128 {
19        self.inner
20    }
21
22    pub fn set<T: Into<i128>>(&mut self, value: T) {
23        self.inner = value.into();
24    }
25
26    pub fn to<T: SerdeIntegerConversion<SIGNED, VARIABLE, BITS>>(&self) -> T {
27        T::from(self)
28    }
29
30    pub fn new<T: Into<i128>>(value: T) -> Self {
31        let inner = Into::<i128>::into(value);
32
33        if inner < 0 && !SIGNED {
34            panic!("can't encode a negative number with an Unsigned Integer!");
35        }
36
37        if BITS == 0 {
38            panic!("can't create an integer with 0 bits...");
39        }
40        if BITS > 127 {
41            panic!("can't create an integer with more than 127 bits...");
42        }
43
44        if !VARIABLE {
45            let max_value: i128 = 2_i128.pow(BITS as u32);
46            if inner >= max_value {
47                panic!(
48                    "with {} bits, can't encode number greater than {}",
49                    BITS, max_value
50                );
51            }
52            if inner < 0 && SIGNED {
53                let min_value: i128 = -(2_i128.pow(BITS as u32));
54                if inner <= min_value {
55                    panic!(
56                        "with {} bits, can't encode number less than {}",
57                        BITS, min_value
58                    );
59                }
60            }
61        }
62
63        Self { inner }
64    }
65
66    fn new_unchecked(value: i128) -> Self {
67        Self { inner: value }
68    }
69}
70
71impl<const SIGNED: bool, const VARIABLE: bool, const BITS: u8> Serde
72    for SerdeInteger<SIGNED, VARIABLE, BITS>
73{
74    fn ser(&self, writer: &mut dyn BitWrite) {
75        let mut value: u128;
76        let negative = self.inner < 0;
77
78        if SIGNED {
79            // 1 if negative, 0 if positive
80            writer.write_bit(negative);
81            if negative {
82                value = -self.inner as u128;
83            } else {
84                value = self.inner as u128;
85            }
86        } else {
87            value = self.inner as u128;
88        }
89
90        if VARIABLE {
91            let mut proceed;
92            loop {
93                if value >= 2_u128.pow(BITS as u32) {
94                    proceed = true;
95                } else {
96                    proceed = false;
97                }
98                writer.write_bit(proceed);
99
100                for _ in 0..BITS {
101                    writer.write_bit(value & 1 != 0);
102                    value >>= 1;
103                }
104                if !proceed {
105                    return;
106                }
107            }
108        } else {
109            for _ in 0..BITS {
110                writer.write_bit(value & 1 != 0);
111                value >>= 1;
112            }
113        }
114    }
115
116    fn de(reader: &mut BitReader) -> Result<Self, SerdeErr> {
117        let mut negative: bool = false;
118        if SIGNED {
119            negative = reader.read_bit()?;
120        }
121
122        if VARIABLE {
123            let mut total_bits: usize = 0;
124            let mut output: u128 = 0;
125
126            loop {
127                let proceed = reader.read_bit()?;
128
129                for _ in 0..BITS {
130                    total_bits += 1;
131
132                    output <<= 1;
133
134                    if reader.read_bit()? {
135                        output |= 1;
136                    }
137                }
138
139                if !proceed {
140                    output <<= 128 - total_bits;
141                    output = output.reverse_bits();
142
143                    let value: i128 = output as i128;
144                    if negative {
145                        return Ok(SerdeInteger::new_unchecked(-value));
146                    } else {
147                        return Ok(SerdeInteger::new_unchecked(value));
148                    }
149                }
150            }
151        } else {
152            let mut output: u128 = 0;
153
154            for _ in 0..BITS {
155                output <<= 1;
156
157                if reader.read_bit()? {
158                    output |= 1;
159                }
160            }
161
162            output <<= 128 - BITS;
163            output = output.reverse_bits();
164
165            let value: i128 = output as i128;
166            if negative {
167                Ok(SerdeInteger::new_unchecked(-value))
168            } else {
169                Ok(SerdeInteger::new_unchecked(value))
170            }
171        }
172    }
173
174    fn bit_length(&self) -> u32 {
175        let mut output: u32 = 0;
176
177        if SIGNED {
178            output += 1;
179        }
180
181        if VARIABLE {
182            let mut proceed;
183            let mut value = self.inner.abs() as u128;
184            loop {
185                if value >= 2_u128.pow(BITS as u32) {
186                    proceed = true;
187                } else {
188                    proceed = false;
189                }
190                output += 1;
191
192                for _ in 0..BITS {
193                    output += 1;
194                    value >>= 1;
195                }
196                if !proceed {
197                    break;
198                }
199            }
200        } else {
201            output += BITS as u32;
202        }
203
204        output
205    }
206}
207
208impl<const SIGNED: bool, const BITS: u8> ConstBitLength for SerdeInteger<SIGNED, false, BITS> {
209    fn const_bit_length() -> u32 {
210        let mut output: u32 = 0;
211
212        if SIGNED {
213            output += 1;
214        }
215
216        output += BITS as u32;
217
218        output
219    }
220}
221
222impl<const SIGNED: bool, const VARIABLE: bool, const BITS: u8, T: Into<i128>> From<T>
223    for SerdeInteger<SIGNED, VARIABLE, BITS>
224{
225    fn from(value: T) -> Self {
226        Self::new(value)
227    }
228}
229
230impl<const SIGNED: bool, const VARIABLE: bool, const BITS: u8, T: TryFrom<i128>>
231    SerdeIntegerConversion<SIGNED, VARIABLE, BITS> for T
232{
233    fn from(value: &SerdeInteger<SIGNED, VARIABLE, BITS>) -> Self {
234        let Ok(t_value) = T::try_from(value.inner) else {
235            panic!("SerdeInteger's value is out of range to convert to this type.");
236        };
237        t_value
238    }
239}
240
241pub trait SerdeIntegerConversion<const SIGNED: bool, const VARIABLE: bool, const BITS: u8> {
242    fn from(value: &SerdeInteger<SIGNED, VARIABLE, BITS>) -> Self;
243}
244
245// Tests
246
247#[cfg(test)]
248mod tests {
249    use crate::{
250        bit_reader::BitReader,
251        bit_writer::BitWriter,
252        integer::{SignedInteger, SignedVariableInteger, UnsignedInteger, UnsignedVariableInteger},
253        serde::Serde,
254    };
255
256    #[test]
257    fn in_and_out() {
258        let in_u16: u16 = 123;
259        let middle = UnsignedInteger::<9>::new(in_u16);
260        let out_u16: u16 = middle.get() as u16;
261
262        assert_eq!(in_u16, out_u16);
263    }
264
265    #[test]
266    fn read_write_unsigned() {
267        // Write
268        let mut writer = BitWriter::new();
269
270        let in_1 = UnsignedInteger::<7>::new(123);
271        let in_2 = UnsignedInteger::<20>::new(535221);
272        let in_3 = UnsignedInteger::<2>::new(3);
273
274        in_1.ser(&mut writer);
275        in_2.ser(&mut writer);
276        in_3.ser(&mut writer);
277
278        let buffer = writer.to_bytes();
279
280        // Read
281        let mut reader = BitReader::new(&buffer);
282
283        let out_1 = Serde::de(&mut reader).unwrap();
284        let out_2 = Serde::de(&mut reader).unwrap();
285        let out_3 = Serde::de(&mut reader).unwrap();
286
287        assert_eq!(in_1, out_1);
288        assert_eq!(in_2, out_2);
289        assert_eq!(in_3, out_3);
290    }
291
292    #[test]
293    fn read_write_signed() {
294        // Write
295        let mut writer = BitWriter::new();
296
297        let in_1 = SignedInteger::<10>::new(-668);
298        let in_2 = SignedInteger::<20>::new(53);
299        let in_3 = SignedInteger::<2>::new(-3);
300
301        in_1.ser(&mut writer);
302        in_2.ser(&mut writer);
303        in_3.ser(&mut writer);
304
305        let buffer = writer.to_bytes();
306
307        // Read
308        let mut reader = BitReader::new(&buffer);
309
310        let out_1 = Serde::de(&mut reader).unwrap();
311        let out_2 = Serde::de(&mut reader).unwrap();
312        let out_3 = Serde::de(&mut reader).unwrap();
313
314        assert_eq!(in_1, out_1);
315        assert_eq!(in_2, out_2);
316        assert_eq!(in_3, out_3);
317    }
318
319    #[test]
320    fn read_write_unsigned_variable() {
321        // Write
322        let mut writer = BitWriter::new();
323
324        let in_1 = UnsignedVariableInteger::<3>::new(23);
325        let in_2 = UnsignedVariableInteger::<5>::new(153);
326        let in_3 = UnsignedVariableInteger::<2>::new(3);
327
328        in_1.ser(&mut writer);
329        in_2.ser(&mut writer);
330        in_3.ser(&mut writer);
331
332        let buffer = writer.to_bytes();
333
334        // Read
335        let mut reader = BitReader::new(&buffer);
336
337        let out_1 = Serde::de(&mut reader).unwrap();
338        let out_2 = Serde::de(&mut reader).unwrap();
339        let out_3 = Serde::de(&mut reader).unwrap();
340
341        assert_eq!(in_1, out_1);
342        assert_eq!(in_2, out_2);
343        assert_eq!(in_3, out_3);
344    }
345
346    #[test]
347    fn read_write_signed_variable() {
348        // Write
349        let mut writer = BitWriter::new();
350
351        let in_1 = SignedVariableInteger::<5>::new(-668);
352        let in_2 = SignedVariableInteger::<6>::new(53735);
353        let in_3 = SignedVariableInteger::<2>::new(-3);
354
355        in_1.ser(&mut writer);
356        in_2.ser(&mut writer);
357        in_3.ser(&mut writer);
358
359        let buffer = writer.to_bytes();
360
361        // Read
362        let mut reader = BitReader::new(&buffer);
363
364        let out_1 = Serde::de(&mut reader).unwrap();
365        let out_2 = Serde::de(&mut reader).unwrap();
366        let out_3 = Serde::de(&mut reader).unwrap();
367
368        assert_eq!(in_1, out_1);
369        assert_eq!(in_2, out_2);
370        assert_eq!(in_3, out_3);
371    }
372}