gel_db_protocol/
encoding.rs

1use std::marker::PhantomData;
2
3use crate::datatypes::*;
4use crate::declare_type;
5use crate::prelude::*;
6use uuid::Uuid;
7
8/// All data types must implement this trait. This allows for encoding and
9/// decoding of the data type to byte buffers.
10pub trait DataType
11where
12    Self: Sized,
13{
14    const META: StructFieldMeta;
15    /// Always a reference
16    type BuilderForEncode;
17    type BuilderForStruct<'unused>;
18    type DecodeLifetime<'a>;
19
20    fn decode<'a>(buf: &mut &'a [u8]) -> Result<Self::DecodeLifetime<'a>, ParseError>;
21    fn encode<'a, 'b>(buf: &mut BufWriter<'a>, value: &'b Self::BuilderForEncode);
22    #[allow(unused)]
23    fn encode_usize<'a>(buf: &mut BufWriter<'a>, value: usize) {
24        unreachable!("encode usize")
25    }
26    #[allow(unused)]
27    fn decode_usize(buf: &mut &[u8]) -> Result<usize, ParseError> {
28        unreachable!("decode usize")
29    }
30}
31
32/// Implemented for all data types that have a fixed size.
33pub trait DataTypeFixedSize {
34    const SIZE: usize;
35}
36
37impl<const N: usize, T: DataType> DataTypeFixedSize for [T; N] {
38    const SIZE: usize = std::mem::size_of::<T>() * N;
39}
40
41#[derive(derive_more::Error, derive_more::Display, Debug, Clone, Copy, PartialEq, Eq)]
42pub enum ParseError {
43    #[display("Buffer is too short")]
44    TooShort,
45    #[display("Invalid data")]
46    InvalidData,
47}
48
49pub struct EncodeTarget<'a> {
50    _phantom: PhantomData<&'a ()>,
51}
52
53impl<'a, L: DataType, T: DataType> DataType for Array<'a, L, T>
54where
55    T::BuilderForEncode: 'a,
56    T::BuilderForStruct<'a>: 'a,
57{
58    const META: StructFieldMeta = declare_meta!(
59        type = Array,
60        constant_size = None,
61        flags = [array]
62    );
63    type BuilderForEncode = &'a [T::BuilderForEncode];
64    type BuilderForStruct<'unused> = &'a [T::BuilderForStruct<'a>];
65    type DecodeLifetime<'__next_lifetime> =
66        Array<'__next_lifetime, L, T::DecodeLifetime<'__next_lifetime>>;
67
68    fn decode<'__next_lifetime>(
69        buf: &mut &'__next_lifetime [u8],
70    ) -> Result<Self::DecodeLifetime<'__next_lifetime>, ParseError> {
71        let len = L::decode_usize(buf)?;
72        let orig_buf = *buf;
73        for _ in 0..len {
74            T::decode(buf)?;
75        }
76        Ok(Array::new(orig_buf, len as _))
77    }
78
79    fn encode<'__buffer_lifetime, '__value_lifetime>(
80        buf: &mut BufWriter<'__buffer_lifetime>,
81        value: &'__value_lifetime Self::BuilderForEncode,
82    ) {
83        L::encode_usize(buf, value.len());
84        for elem in value.iter() {
85            T::encode(buf, elem);
86        }
87    }
88}
89
90impl<'a, T: DataType> DataType for ZTArray<'a, T>
91where
92    T::BuilderForEncode: 'a,
93    T::BuilderForStruct<'a>: 'a,
94{
95    const META: StructFieldMeta = declare_meta!(
96        type = ZTArray,
97        constant_size = None,
98        flags = [array]
99    );
100    type BuilderForEncode = &'a [T::BuilderForEncode];
101    type BuilderForStruct<'unused> = &'a [T::BuilderForStruct<'a>];
102    type DecodeLifetime<'__next_lifetime> =
103        ZTArray<'__next_lifetime, T::DecodeLifetime<'__next_lifetime>>;
104
105    fn decode<'__next_lifetime>(
106        buf: &mut &'__next_lifetime [u8],
107    ) -> Result<Self::DecodeLifetime<'__next_lifetime>, ParseError> {
108        let mut orig_buf = *buf;
109        let mut len = 0;
110        loop {
111            if buf.is_empty() {
112                return Err(crate::prelude::ParseError::TooShort);
113            }
114            if buf[0] == 0 {
115                orig_buf = &orig_buf[0..orig_buf.len() - buf.len() + 1];
116                *buf = &buf[1..];
117                break;
118            }
119            T::decode(buf)?;
120            len += 1;
121        }
122        Ok(ZTArray::new(orig_buf, len))
123    }
124
125    fn encode<'__buffer_lifetime, '__value_lifetime>(
126        buf: &mut BufWriter<'__buffer_lifetime>,
127        value: &'__value_lifetime Self::BuilderForEncode,
128    ) {
129        for elem in value.iter() {
130            T::encode(buf, elem);
131        }
132        buf.write(&[0]);
133    }
134}
135
136impl<const N: usize, T: DataType> DataType for [T; N]
137where
138    for<'a> T::DecodeLifetime<'a>: Default + Copy,
139{
140    const META: StructFieldMeta = declare_meta!(
141        type = FixedArray,
142        constant_size = Some(std::mem::size_of::<T>() * N),
143        flags = [array]
144    );
145    type BuilderForStruct<'unused> = [T::BuilderForStruct<'unused>; N];
146    type BuilderForEncode = [T::BuilderForEncode; N];
147    type DecodeLifetime<'__next_lifetime> = [T::DecodeLifetime<'__next_lifetime>; N];
148    fn decode<'__next_lifetime>(
149        buf: &mut &'__next_lifetime [u8],
150    ) -> Result<Self::DecodeLifetime<'__next_lifetime>, crate::prelude::ParseError> {
151        let mut res = [T::DecodeLifetime::<'__next_lifetime>::default(); N];
152        for i in 0..N {
153            res[i] = T::decode(buf)?;
154        }
155        Ok(res)
156    }
157    fn encode<'__buffer_lifetime, '__value_lifetime>(
158        buf: &mut crate::prelude::BufWriter<'__buffer_lifetime>,
159        value: &'__value_lifetime Self::BuilderForEncode,
160    ) {
161        for elem in value {
162            T::encode(buf, elem);
163        }
164    }
165}
166
167declare_type!(DataType, Rest<'a>, builder: &'a [u8],
168{
169    fn decode(buf: &mut &[u8]) -> Result<Self, ParseError> {
170        let res = Rest::new(buf);
171        *buf = &[];
172        Ok(res)
173    }
174
175    fn encode(buf: &mut BufWriter, value: &[u8]) {
176        buf.write(value)
177    }
178}
179);
180
181declare_type!(DataType, LString<'a>, builder: &'a str, {
182    fn decode(buf: &mut &[u8]) -> Result<Self, ParseError> {
183        let arr = Array::<u32, u8>::decode(buf)?;
184        Ok(LString::new(arr.into_slice()))
185    }
186    fn encode(buf: &mut BufWriter, value: &str) {
187        Array::<u32, u8>::encode(buf, &value.as_bytes());
188    }
189});
190declare_type!(DataType, ZTString<'a>, builder: &'a str, {
191    fn decode(buf: &mut &[u8]) -> Result<Self, ParseError> {
192        let arr = ZTArray::<u8>::decode(buf)?;
193        let slice = arr.into_slice();
194        Ok(ZTString::new(&slice[0..slice.len() - 1]))
195    }
196    fn encode(buf: &mut BufWriter, value: &str) {
197        ZTArray::<u8>::encode(buf, &value.as_bytes());
198    }
199});
200
201declare_type!(DataType, Encoded<'a>, builder: Encoded<'a>, {
202    fn decode(buf: &mut &[u8]) -> Result<Self, ParseError> {
203        if let Some((len, array)) = buf.split_first_chunk::<{std::mem::size_of::<i32>()}>() {
204            let len = i32::from_be_bytes(*len);
205            if len == -1 {
206                *buf = array;
207                Ok(Encoded::Null)
208            } else if len < 0 {
209                Err(ParseError::InvalidData)
210            } else if array.len() < len as _ {
211                Err(ParseError::TooShort)
212            } else {
213                *buf = &array[len as usize..];
214                Ok(Encoded::Value(&array[..len as usize]))
215            }
216        } else {
217            Err(ParseError::TooShort)
218        }
219    }
220    fn encode(buf: &mut BufWriter, value: &Encoded<'a>) {
221        match value {
222            Encoded::Null => buf.write(&(-1_i32).to_be_bytes()),
223            Encoded::Value(value) => {
224                let len: i32 = value.len() as _;
225                buf.write(&len.to_be_bytes());
226                buf.write(value);
227            }
228        }
229    }
230});
231
232declare_type!(DataType, Length, flags = [length], {
233    fn decode(buf: [u8; 4]) -> Result<Self, ParseError> {
234        Ok(Self(i32::from_be_bytes(buf)))
235    }
236    fn encode(value: u32) -> [u8; 4] {
237        value.0.to_be_bytes()
238    }
239    fn to_usize(value: usize) -> Length {
240        Length(value as _)
241    }
242    fn from_usize(value: Length) -> usize {
243        value.0 as usize
244    }
245});
246
247declare_type!(DataType, Uuid, {
248    fn decode(buf: [u8; 16]) -> Result<Self, ParseError> {
249        Ok(Uuid::from_bytes(buf))
250    }
251    fn encode(value: Uuid) -> [u8; 16] {
252        value.into_bytes()
253    }
254});
255
256declare_type!(u8);
257declare_type!(u16);
258declare_type!(u32);
259declare_type!(u64);
260declare_type!(i8);
261declare_type!(i16);
262declare_type!(i32);
263declare_type!(i64);
264
265declare_type!(f32);
266declare_type!(f64);