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
use crate::*;

impl DataType<'_> for bool {
    const IS_DYNAMIC: bool = false;

    #[inline]
    fn serialize(self, view: &mut Cursor<impl Bytes>) {
        u8::serialize(self.into(), view);
    }
    #[inline]
    fn deserialize(view: &mut Cursor<&[u8]>) -> Result<Self> {
        u8::deserialize(view).map(|v| v != 0)
    }
}
impl DataType<'_> for char {
    const IS_DYNAMIC: bool = false;

    #[inline]
    fn serialize(self, view: &mut Cursor<impl Bytes>) {
        u32::serialize(self.into(), view);
    }
    #[inline]
    fn deserialize(view: &mut Cursor<&[u8]>) -> Result<Self> {
        char::from_u32(u32::deserialize(view)?).ok_or(InvalidChar)
    }
}
macro_rules! impl_data_type_for {
    [$($rty:ty)*] => ($(
        impl DataType<'_> for $rty {
            const IS_DYNAMIC: bool = false;

            #[inline]
            fn serialize(self, view: &mut Cursor<impl Bytes>) {
                unsafe {
                    let data = view.data.as_mut();
                    let dst = data.as_mut_ptr().add(view.offset);

                    let total_len = view.offset + size_of::<Self>();
                    view.data.new_len(total_len, size_of::<Self>());

                    view.offset = total_len;
                    write_num!(self, dst);
                }
            }
            #[inline]
            fn deserialize(view: &mut Cursor<&[u8]>) -> Result<Self> {
                unsafe {
                    let total_len = view.offset + size_of::<Self>();
                    if total_len > view.data.len() { return Err(InsufficientBytes); }
                    
                    let src = view.data.as_ptr().add(view.offset);
                    view.offset = total_len;
                    read_num!(src);
                };
            }
        }
    )*);
}
macro_rules! read_num {
    [$src: expr] => {
        #[cfg(all(target_endian = "big", not(any(feature = "BE", feature = "NE"))))]
        return Ok(Self::from_le_bytes(read_unaligned($src)));
        #[cfg(all(target_endian = "little", feature = "BE"))]
        return Ok(Self::from_be_bytes(read_unaligned($src)));
        #[cfg(any(
            feature = "NE",
            all(target_endian = "big", feature = "BE"),
            all(target_endian = "little", not(any(feature = "BE", feature = "NE"))),
        ))]
        return Ok(read_unaligned($src));
    };
}
macro_rules! write_num {
    [$val:tt, $dst: expr] => (
        #[cfg(all(target_endian = "big", not(any(feature = "BE", feature = "NE"))))]
        write_unaligned($val.to_le_bytes().as_ptr() , $dst, size_of::<Self>());
        #[cfg(all(target_endian = "little", feature = "BE"))]
        write_unaligned($val.to_be_bytes().as_ptr() , $dst, size_of::<Self>());
        #[cfg(any(
            feature = "NE",
            all(target_endian = "big", feature = "BE"),
            all(target_endian = "little", not(any(feature = "BE", feature = "NE"))),
        ))]
        write_unaligned(&$val as *const Self as *const u8, $dst, size_of::<Self>());
    )
}
impl_data_type_for!(
    u8 u16 u32 u64 u128
    i8 i16 i32 i64 i128
    usize isize
    f32 f64
);

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

unsafe fn read_unaligned<T>(src: *const u8) -> T {
    let mut tmp = MaybeUninit::<T>::uninit();
    ptr::copy_nonoverlapping(src, tmp.as_mut_ptr() as *mut u8, size_of::<T>());
    tmp.assume_init()
}
unsafe fn write_unaligned(src: *const u8, dst: *mut u8, count: usize) {
    ptr::copy_nonoverlapping(src, dst, count);
}