alkahest/
primitive.rs

1use core::{borrow::Borrow, mem::size_of};
2
3use crate::{
4    buffer::Buffer,
5    deserialize::{Deserialize, DeserializeError, Deserializer},
6    formula::{BareFormula, Formula},
7    serialize::{write_bytes, Serialize, SerializeRef, Sizes},
8};
9
10macro_rules! impl_primitive {
11    () => {};
12
13    ([$($head:ident)+] $([$($tail:ident)+])*) => {
14        impl_primitive!(@ < $($head)+);
15        impl_primitive!($([$($tail)+])*);
16    };
17
18    (@ $($head:ident)* <) => {};
19    (@ $($head:ident)* < $cursor:ident $($tail:ident)*) => {
20        impl_primitive!{! $($head)* < $cursor < $($tail)* }
21        impl_primitive!{@ $($head)* $cursor < $($tail)* }
22    };
23
24    (! $($from:ident)* < $ty:ident < $($to:ident)*) => {
25        impl Formula for $ty {
26            const MAX_STACK_SIZE: Option<usize> = Some(size_of::<$ty>());
27            const EXACT_SIZE: bool = true;
28            const HEAPLESS: bool = true;
29        }
30
31        impl BareFormula for $ty {}
32
33        impl Serialize<$ty> for $ty {
34            #[inline(always)]
35            fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
36            where
37                B: Buffer,
38            {
39                write_bytes(&self.to_le_bytes(), sizes, buffer)
40            }
41
42            #[inline(always)]
43            fn size_hint(&self) -> Option<Sizes> {
44                Some(Sizes{ heap: 0, stack: size_of::<$ty>()})
45            }
46        }
47
48        $(
49            impl Serialize<$ty> for $from {
50                #[inline(always)]
51                fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
52                where
53                    B: Buffer,
54                {
55                    write_bytes(&$ty::from(self).to_le_bytes(), sizes, buffer)
56                }
57
58                #[inline(always)]
59                fn size_hint(&self) -> Option<Sizes> {
60                    Some(Sizes{ heap: 0, stack: size_of::<$ty>()})
61                }
62            }
63        )*
64
65        impl SerializeRef<$ty> for $ty {
66            #[inline(always)]
67            fn serialize<B>(&self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
68            where
69                B: Buffer,
70            {
71                write_bytes(&self.to_le_bytes(), sizes, buffer)
72            }
73
74            #[inline(always)]
75            fn size_hint(&self) -> Option<Sizes> {
76                Some(Sizes{ heap: 0, stack: size_of::<$ty>()})
77            }
78        }
79
80        $(
81            impl SerializeRef<$ty> for $from {
82                #[inline(always)]
83                fn serialize<B>(&self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
84                where
85                    B: Buffer,
86                {
87                    write_bytes(&$ty::from(*self).to_le_bytes(), sizes, buffer)
88                }
89
90                #[inline(always)]
91                fn size_hint(&self) -> Option<Sizes> {
92                    Some(Sizes{ heap: 0, stack: size_of::<$ty>()})
93                }
94            }
95        )*
96
97        impl<T> Deserialize<'_, $ty> for T
98        where
99            T: From<$ty>,
100        {
101            #[inline(always)]
102            fn deserialize(mut de: Deserializer) -> Result<Self, DeserializeError> {
103                let input = de.read_byte_array::<{size_of::<$ty>()}>()?;
104                // de.finish()?;
105                let value = <$ty>::from_le_bytes(input);
106                return Ok(From::from(value));
107            }
108
109            #[inline(always)]
110            fn deserialize_in_place(&mut self, mut de: Deserializer) -> Result<(), DeserializeError> {
111                let input = de.read_byte_array::<{size_of::<$ty>()}>()?;
112                // de.finish()?;
113                let value = <$ty>::from_le_bytes(input);
114                *self = From::from(value);
115                Ok(())
116            }
117        }
118    };
119}
120
121impl_primitive! {
122    [u8 u16 u32 u64 u128]
123    [i8 i16 i32 i64 i128]
124    [f32 f64]
125}
126
127impl Formula for bool {
128    const MAX_STACK_SIZE: Option<usize> = Some(1);
129    const EXACT_SIZE: bool = true;
130    const HEAPLESS: bool = true;
131}
132
133impl BareFormula for bool {}
134
135impl Serialize<bool> for bool {
136    #[inline(always)]
137    fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
138    where
139        Self: Sized,
140        B: Buffer,
141    {
142        write_bytes(&[u8::from(self)], sizes, buffer)
143    }
144
145    #[inline(always)]
146    fn size_hint(&self) -> Option<Sizes> {
147        Some(Sizes {
148            heap: 0,
149            stack: size_of::<u8>(),
150        })
151    }
152}
153
154impl Serialize<bool> for &bool {
155    #[inline(always)]
156    fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
157    where
158        B: Buffer,
159    {
160        <u8 as Serialize<u8>>::serialize(u8::from(*self.borrow()), sizes, buffer)
161    }
162
163    #[inline(always)]
164    fn size_hint(&self) -> Option<Sizes> {
165        Some(Sizes {
166            heap: 0,
167            stack: size_of::<u8>(),
168        })
169    }
170}
171
172impl<T> Deserialize<'_, bool> for T
173where
174    T: From<bool>,
175{
176    #[inline(always)]
177    fn deserialize(mut de: Deserializer) -> Result<Self, DeserializeError> {
178        let byte = de.read_byte()?;
179        Ok(T::from(byte != 0))
180    }
181
182    #[inline(always)]
183    fn deserialize_in_place(&mut self, mut de: Deserializer) -> Result<(), DeserializeError> {
184        let byte = de.read_byte()?;
185        *self = From::from(byte != 0);
186        Ok(())
187    }
188}