gel_db_protocol/
macros.rs

1/// This macro is used to declare serialization traits for a type.
2#[macro_export]
3macro_rules! declare_type {
4    // Primitive types (no lifetime, fixed size)
5    ($ty:ident) =>
6    {
7        $crate::declare_type!($crate::prelude::DataType, $ty, {
8            fn decode(buf: [u8; N]) -> Result<Self, ParseError> {
9                Ok($ty::from_be_bytes(buf))
10            }
11            fn encode(value: $ty) -> [u8; N] {
12                value.to_be_bytes()
13            }
14            fn to_usize(value: usize) -> $ty {
15                value as $ty
16            }
17            fn from_usize(value: $ty) -> usize {
18                value as usize
19            }
20        });
21    };
22    ($datatype:path, $ty:ident , $( flags=[$($flag:ident),*], )?
23    {
24        fn decode($ebuf:ident: [u8; $dsize:expr]) -> Result<Self, ParseError> $decode:block
25        fn encode($evalue:ident: $encode_type:ty) -> [u8; $esize:expr] $encode:block
26        $( fn to_usize($eusize:ident: usize) -> $eusize_self:ty $to_usize:block )?
27        $( fn from_usize($eusize2:ident: $eusize_self2:ty) -> usize $from_usize:block )?
28    }
29        ) => {
30        impl $datatype for $ty {
31            const META: $crate::prelude::StructFieldMeta = $crate::prelude::declare_meta!(
32                type = $ty,
33                constant_size = Some(std::mem::size_of::<$ty>()),
34                flags = [$($($flag),*)?]
35            );
36            type BuilderForStruct<'unused> = $ty;
37            type BuilderForEncode = $ty;
38            type DecodeLifetime<'a> = $ty;
39            fn decode(buf: &mut &[u8]) -> Result<Self, $crate::prelude::ParseError> {
40                if let Some((chunk, next)) = buf.split_first_chunk::<{std::mem::size_of::<$ty>()}>() {
41                    let res = {
42                        let $ebuf = *chunk;
43                        $decode
44                    };
45                    *buf = next;
46                    res
47                } else {
48                    Err($crate::prelude::ParseError::TooShort)
49                }
50            }
51            fn encode<'__buffer_lifetime, '__value_lifetime>(buf: &mut $crate::prelude::BufWriter<'__buffer_lifetime>, value: &'__value_lifetime Self::BuilderForEncode) {
52                let $evalue = *value;
53                let bytes = $encode;
54                buf.write(&bytes);
55            }
56            $(
57                fn encode_usize<'__buffer_lifetime, '__value_lifetime>(buf: &mut $crate::prelude::BufWriter<'__buffer_lifetime>, value: usize) {
58                    let $eusize = value;
59                    let value = $to_usize;
60                    Self::encode(buf, &value);
61                }
62                fn decode_usize(buf: &mut &[u8]) -> Result<usize, $crate::prelude::ParseError> {
63                    let $eusize2 = Self::decode(buf)?;
64                    Ok($from_usize)
65                }
66            )?
67        }
68
69        impl $crate::prelude::DataTypeFixedSize for $ty {
70            const SIZE: usize = std::mem::size_of::<$ty>();
71        }
72
73    };
74
75    // Lifetime type, non-fixed size
76    ($datatype:path, $ty:ident<$lt:lifetime>, builder: $builder:ty, $( flags=[$($flag:ident),*], )?
77    {
78        fn decode($dbuf:ident: &mut &[u8]) -> Result<Self, ParseError> $decode:block
79        fn encode($ebuf:ident: &mut BufWriter, $evalue:ident: $encode_type:ty) $encode:block
80    }) => {
81        impl <$lt> $datatype
82            for $ty<$lt> {
83            const META: $crate::prelude::StructFieldMeta = $crate::prelude::declare_meta!(
84                type = $ty,
85                constant_size = None,
86                flags = [$($($flag),*)?]
87            );
88            type BuilderForStruct<'unused> = $builder;
89            type BuilderForEncode = $builder;
90            type DecodeLifetime<'__next_lifetime> = $ty<'__next_lifetime>;
91            fn decode<'__next_lifetime>(buf: &mut &'__next_lifetime [u8]) -> Result<Self::DecodeLifetime<'__next_lifetime>, $crate::prelude::ParseError> {
92                let $dbuf = buf;
93                $decode
94            }
95            fn encode<'__buffer_lifetime, '__value_lifetime>(buf: &mut $crate::prelude::BufWriter<'__buffer_lifetime>, value: &'__value_lifetime Self::BuilderForEncode) {
96                let $ebuf = buf;
97                let $evalue = value;
98                $encode
99            }
100        }
101    };
102}
103
104#[macro_export]
105macro_rules! declare_meta {
106    (type = $ty:ident, constant_size = $constant_size:expr, flags = [$($flag:ident),*]) => {
107        $crate::paste!($crate::prelude::StructFieldMeta::new(stringify!($ty), $constant_size)
108            $(
109                .[< set_ $flag >]()
110            )*)
111
112    };
113}