1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
use crate::*;

impl Encoder for bool {
    #[inline]
    fn encoder(&self, writer: &mut impl Write) -> io::Result<()> {
        writer.write_all(&[*self as u8])
    }
}

impl Decoder<'_> for bool {
    #[inline]
    fn decoder(c: &mut &[u8]) -> Result<Self> {
        u8::decoder(c).map(|byte| byte != 0)
    }
}

impl Encoder for char {
    #[inline]
    fn encoder(&self, c: &mut impl Write) -> io::Result<()> {
        u32::from(*self).encoder(c)
    }
}
impl Decoder<'_> for char {
    #[inline]
    fn decoder(c: &mut &[u8]) -> Result<Self> {
        let num = u32::decoder(c)?;
        char::from_u32(num).ok_or_else(|| format!("{num} is not a valid char").into())
    }
}

// ----------------------------------------------------------------------------------------------

impl Encoder for u8 {
    #[inline]
    fn encoder(&self, writer: &mut impl Write) -> io::Result<()> {
        writer.write_all(&[*self])
    }
}

impl Decoder<'_> for u8 {
    #[inline]
    fn decoder(reader: &mut &[u8]) -> Result<Self> {
        if !reader.is_empty() {
            unsafe {
                let slice = reader.get_unchecked(0);
                *reader = reader.get_unchecked(1..);
                Ok(*slice)
            }
        } else {
            Err("Insufficient bytes".into())
        }
    }
}

impl Encoder for i8 {
    #[inline]
    fn encoder(&self, writer: &mut impl Write) -> io::Result<()> {
        writer.write_all(&[*self as u8])
    }
}
impl Decoder<'_> for i8 {
    #[inline]
    fn decoder(c: &mut &[u8]) -> Result<Self> {
        u8::decoder(c).map(|byte| byte as i8)
    }
}
macro_rules! impl_data_type_for {
    [$($rty:ty)*] => ($(
        impl Encoder for $rty {
            #[inline] fn encoder(&self, writer: &mut impl Write) -> io::Result<()> {
                #[cfg(not(any(feature = "BE", feature = "NE")))]
                return writer.write_all(&self.to_le_bytes());
                #[cfg(feature = "BE")]
                return writer.write_all(&self.to_be_bytes());
                #[cfg(feature = "NE")]
                return writer.write_all(&self.to_ne_bytes());
            }
        }
        impl Decoder<'_> for $rty {
            #[inline] fn decoder(c: &mut &[u8]) -> Result<Self> {
                let arr = <&[u8; std::mem::size_of::<Self>()]>::decoder(c)?;
                #[cfg(not(any(feature = "BE", feature = "NE")))]
                return Ok(Self::from_le_bytes(*arr));
                #[cfg(feature = "BE")]
                return Ok(Self::from_be_bytes(*arr));
                #[cfg(feature = "NE")]
                return Ok(Self::from_ne_bytes(*arr));
            }
        }
    )*);
}

impl_data_type_for!(
    u16 u32 u64 u128
    i16 i32 i64 i128
    usize isize
    f32 f64
);

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_scaler_type() {
        for word in [0x_A5C11, 0x_C0DE, 0x_DEC0DE, 0x_ADDED, 0x_AB0DE, 0x_CAFE] {
            assert_eq!(word, u32::decode(&word.encode()).unwrap());
        }
        for word in [
            0x_DEAD_BEEF,
            0x_Faded_Face,
            0x_BAD_F00D,
            0x_C01D_C0FFEE,
            0x_C0CA_C01A,
        ] {
            assert_eq!(word, u64::decode(&word.encode()).unwrap());
        }
    }
}