encdec_base/
primitives.rs

1//! Encode/Decode implementations for primitive types
2//!
3
4use byteorder::{ByteOrder, LittleEndian as LE};
5
6use crate::{DecodeOwned, Encode, Error};
7
8/// Helper trait to implement encode/decode on fixed size types
9trait FixedEncDec: Sized {
10    const N: usize;
11
12    fn e(&self, buff: &mut [u8]) -> ();
13    fn d(buff: &[u8]) -> Self;
14}
15
16/// Helper macro for implementing primitive encode / decode
17macro_rules! impl_encdec {
18    ($t:ty, $n:literal, $d:expr, $e:expr) => {
19        impl DecodeOwned for $t {
20            type Output = $t;
21            type Error = Error;
22
23            #[inline]
24            fn decode_owned(buff: &[u8]) -> Result<(Self::Output, usize), Self::Error> {
25                if buff.len() < $n {
26                    return Err(Error::Length);
27                }
28
29                let v = $d(&buff[..$n]);
30
31                Ok((v, $n))
32            }
33        }
34
35        impl Encode for $t {
36            type Error = Error;
37
38            #[inline]
39            fn encode_len(&self) -> Result<usize, Self::Error> {
40                Ok($n)
41            }
42
43            #[inline]
44            fn encode(&self, buff: &mut [u8]) -> Result<usize, Self::Error> {
45                if buff.len() < $n {
46                    return Err(Error::Length);
47                }
48
49                $e(&mut buff[..$n], *self);
50
51                Ok($n)
52            }
53        }
54    };
55}
56
57impl_encdec!(u8, 1, get_u8, put_u8);
58impl_encdec!(i8, 1, get_i8, put_i8);
59impl_encdec!(u16, 2, LE::read_u16, LE::write_u16);
60impl_encdec!(i16, 2, LE::read_i16, LE::write_i16);
61impl_encdec!(u32, 4, LE::read_u32, LE::write_u32);
62impl_encdec!(i32, 4, LE::read_i32, LE::write_i32);
63impl_encdec!(u64, 8, LE::read_u64, LE::write_u64);
64impl_encdec!(i64, 8, LE::read_i64, LE::write_i64);
65impl_encdec!(f32, 4, LE::read_f32, LE::write_f32);
66impl_encdec!(f64, 8, LE::read_f64, LE::write_f64);
67
68#[inline]
69fn get_u8(buff: &[u8]) -> u8 {
70    buff[0]
71}
72
73#[inline]
74fn get_i8(buff: &[u8]) -> i8 {
75    buff[0] as i8
76}
77
78#[inline]
79fn put_u8(buff: &mut [u8], val: u8) {
80    buff[0] = val;
81}
82
83#[inline]
84fn put_i8(buff: &mut [u8], val: i8) {
85    buff[0] = val as u8;
86}