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
120
121
122
123
124
use crate::{Decode, Encode};
use fast_collections::{Cursor, CursorReadTransmute, PushTransmute, String, Vec};

macro_rules! impl_encoder_and_decoder {
    ($($name:ident),*) => {
        $(
        impl Encode for $name {
            #[inline(always)]
            fn encode<const N: usize>(
                &self,
                write_cursor: &mut fast_collections::Cursor<u8, N>,
            ) -> Result<(), ()>
            {
                write_cursor.push_transmute(Self::to_be_bytes(*self))?;
                Ok(())
            }
        }
        impl Decode for $name
        {
            #[inline(always)]
            fn decode<const N: usize>(read_cursor: &mut fast_collections::Cursor<u8, N>) -> Result<Self, ()> {
                CursorReadTransmute::read_transmute::<[u8; _]>(read_cursor)
                    .map(|v| Self::from_be_bytes(*v))
                    .ok_or_else(|| ())
            }
        }
        )*
    };
}

impl Encode for bool {
    #[inline(always)]
    fn encode<const N: usize>(
        &self,
        write_cursor: &mut fast_collections::Cursor<u8, N>,
    ) -> Result<(), ()> {
        write_cursor.push_transmute(Self::from(*self))?;
        Ok(())
    }
}

impl Decode for bool {
    fn decode<const N: usize>(
        read_cursor: &mut fast_collections::Cursor<u8, N>,
    ) -> Result<Self, ()> {
        CursorReadTransmute::read_transmute::<Self>(read_cursor)
            .map(|v| *v)
            .ok_or_else(|| ())
    }
}

impl_encoder_and_decoder! {
    usize, isize,
    u8,    i8,
    u16,   i16,
    u32,   i32,
    u64,   i64,
    u128,  i128,
    f32, f64
}

impl<const VecLen: usize> Encode for Vec<u8, VecLen> {
    fn encode<const CursorLen: usize>(
        &self,
        write_cursor: &mut Cursor<u8, CursorLen>,
    ) -> Result<(), ()> {
        let len = self.len();
        unsafe {
            let encoded_len =
                integer_encoding::VarInt::encode_var(len, write_cursor.unfilled_mut());
            if encoded_len == 0 {
                return Err(());
            }
            let filled_len_mut = write_cursor.filled_len_mut();
            let filled_len_0 = *filled_len_mut;
            let filled_len_1 = filled_len_0.unchecked_add(encoded_len);
            let filled_len_2 = filled_len_1.unchecked_add(len);
            if encoded_len + len >= CursorLen - filled_len_0 {
                return Err(());
            }
            *filled_len_mut = filled_len_2;
            write_cursor.as_array()[filled_len_1..filled_len_2]
                .copy_from_slice(&self.as_array()[..len]);
        }
        Ok(())
    }
}

impl<const VecLen: usize> Decode for Vec<u8, VecLen> {
    fn decode<const CursorLen: usize>(read_cursor: &mut Cursor<u8, CursorLen>) -> Result<Self, ()> {
        let mut vec = Vec::<u8, VecLen>::uninit();
        let pos = read_cursor.pos();
        let filled = &read_cursor.filled()[pos..];
        let (length, read_length) =
            <u32 as integer_encoding::VarInt>::decode_var(filled).ok_or_else(|| ())?;
        let length = length as usize;
        let read_length_plus_length = unsafe { read_length.unchecked_add(length) };
        let new_pos = unsafe { pos.unchecked_add(read_length_plus_length) };
        if filled.len() < read_length_plus_length {
            return Err(());
        }
        vec.as_array_mut()[..length].copy_from_slice(&filled[read_length..read_length_plus_length]);
        *unsafe { read_cursor.pos_mut() } = new_pos;
        *unsafe { vec.len_mut() } = length;
        Ok(vec)
    }
}

impl<const StrLen: usize> Encode for String<StrLen> {
    fn encode<const CursorLen: usize>(
        &self,
        write_cursor: &mut Cursor<u8, CursorLen>,
    ) -> Result<(), ()> {
        let vec: &Vec<u8, StrLen> = unsafe { fast_collections::const_transmute_unchecked(self) };
        Encode::encode(vec, write_cursor)
    }
}

impl<const StrLen: usize> Decode for String<StrLen> {
    fn decode<const CursorLen: usize>(read_cursor: &mut Cursor<u8, CursorLen>) -> Result<Self, ()> {
        let vec: Vec<u8, StrLen> = Decode::decode(read_cursor)?;
        Ok(unsafe { fast_collections::const_transmute_unchecked(vec) })
    }
}