Skip to main content

vsdb/common/
ende.rs

1//!
2//! # EnDe (Encode/Decode)
3//!
4//! This module provides traits for encoding and decoding keys and values.
5//! These traits are used by the various data structures in `vsdb` to serialize
6//! and deserialize data for storage.
7//!
8
9use super::RawBytes;
10use ruc::*;
11use std::{fmt, mem::size_of};
12
13use serde::{Serialize, de::DeserializeOwned};
14
15/////////////////////////////////////////////////////////////////////////////
16/////////////////////////////////////////////////////////////////////////////
17
18/// A trait for encoding keys.
19pub trait KeyEn: Sized {
20    /// Tries to encode the key into a byte vector.
21    fn try_encode_key(&self) -> Result<RawBytes>;
22
23    /// Encodes the key into a byte vector, panicking on failure.
24    fn encode_key(&self) -> RawBytes {
25        pnk!(self.try_encode_key())
26    }
27}
28
29/// A trait for decoding keys.
30pub trait KeyDe: Sized {
31    /// Decodes a key from a byte slice.
32    fn decode_key(bytes: &[u8]) -> Result<Self>;
33}
34
35/// A trait for both encoding and decoding keys.
36pub trait KeyEnDe: Sized {
37    /// Tries to encode the key into a byte vector.
38    fn try_encode(&self) -> Result<RawBytes>;
39
40    /// Encodes the key into a byte vector, panicking on failure.
41    fn encode(&self) -> RawBytes {
42        pnk!(self.try_encode())
43    }
44
45    /// Decodes a key from a byte slice.
46    fn decode(bytes: &[u8]) -> Result<Self>;
47}
48
49/// A trait for encoding values.
50pub trait ValueEn: Sized {
51    /// Tries to encode the value into a byte vector.
52    fn try_encode_value(&self) -> Result<RawBytes>;
53
54    /// Encodes the value into a byte vector, panicking on failure.
55    fn encode_value(&self) -> RawBytes {
56        pnk!(self.try_encode_value())
57    }
58}
59
60/// A trait for decoding values.
61pub trait ValueDe: Sized {
62    /// Decodes a value from a byte slice.
63    fn decode_value(bytes: &[u8]) -> Result<Self>;
64}
65
66/// A trait for both encoding and decoding values.
67pub trait ValueEnDe: Sized {
68    /// Tries to encode the value into a byte vector.
69    fn try_encode(&self) -> Result<RawBytes>;
70
71    /// Encodes the value into a byte vector, panicking on failure.
72    fn encode(&self) -> RawBytes {
73        pnk!(self.try_encode())
74    }
75
76    /// Decodes a value from a byte slice.
77    fn decode(bytes: &[u8]) -> Result<Self>;
78}
79
80impl<T: Serialize> KeyEn for T {
81    fn try_encode_key(&self) -> Result<RawBytes> {
82        serde_cbor_2::to_vec(self).c(d!())
83    }
84}
85
86impl<T: DeserializeOwned> KeyDe for T {
87    fn decode_key(bytes: &[u8]) -> Result<Self> {
88        serde_cbor_2::from_slice(bytes).c(d!())
89    }
90}
91
92impl<T: Serialize> ValueEn for T {
93    fn try_encode_value(&self) -> Result<RawBytes> {
94        serde_cbor_2::to_vec(self).c(d!())
95    }
96}
97
98impl<T: DeserializeOwned> ValueDe for T {
99    fn decode_value(bytes: &[u8]) -> Result<Self> {
100        serde_cbor_2::from_slice(bytes).c(d!())
101    }
102}
103
104impl<T: KeyEn + KeyDe> KeyEnDe for T {
105    fn try_encode(&self) -> Result<RawBytes> {
106        <Self as KeyEn>::try_encode_key(self).c(d!())
107    }
108
109    fn encode(&self) -> RawBytes {
110        <Self as KeyEn>::encode_key(self)
111    }
112
113    fn decode(bytes: &[u8]) -> Result<Self> {
114        <Self as KeyDe>::decode_key(bytes).c(d!())
115    }
116}
117
118impl<T: ValueEn + ValueDe> ValueEnDe for T {
119    fn try_encode(&self) -> Result<RawBytes> {
120        <Self as ValueEn>::try_encode_value(self).c(d!())
121    }
122
123    fn encode(&self) -> RawBytes {
124        <Self as ValueEn>::encode_value(self)
125    }
126
127    fn decode(bytes: &[u8]) -> Result<Self> {
128        <Self as ValueDe>::decode_value(bytes).c(d!())
129    }
130}
131
132/////////////////////////////////////////////////////////////////////////////
133/////////////////////////////////////////////////////////////////////////////
134
135/// A trait for keys that maintain their order when serialized.
136///
137/// This trait is crucial for ordered data structures like `MapxOrd`, ensuring that
138/// operations like range queries work correctly.
139pub trait KeyEnDeOrdered: Clone + Eq + Ord + fmt::Debug {
140    /// Encodes the key into a byte vector.
141    fn to_bytes(&self) -> RawBytes;
142
143    /// Consumes the key and encodes it into a byte vector.
144    fn into_bytes(self) -> RawBytes {
145        self.to_bytes()
146    }
147
148    /// Decodes a key from a byte slice.
149    fn from_slice(b: &[u8]) -> Result<Self>;
150
151    /// Consumes a byte vector and decodes it into a key.
152    fn from_bytes(b: RawBytes) -> Result<Self> {
153        Self::from_slice(&b)
154    }
155}
156
157impl KeyEnDeOrdered for RawBytes {
158    #[inline(always)]
159    fn to_bytes(&self) -> RawBytes {
160        self.clone()
161    }
162
163    #[inline(always)]
164    fn into_bytes(self) -> RawBytes {
165        self
166    }
167
168    #[inline(always)]
169    fn from_slice(b: &[u8]) -> Result<Self> {
170        Ok(b.to_vec())
171    }
172
173    #[inline(always)]
174    fn from_bytes(b: RawBytes) -> Result<Self> {
175        Ok(b.to_vec())
176    }
177}
178
179impl KeyEnDeOrdered for Box<[u8]> {
180    #[inline(always)]
181    fn to_bytes(&self) -> RawBytes {
182        self.clone().to_vec()
183    }
184
185    #[inline(always)]
186    fn into_bytes(self) -> RawBytes {
187        self.to_vec()
188    }
189
190    #[inline(always)]
191    fn from_slice(b: &[u8]) -> Result<Self> {
192        Ok(b.to_vec().into())
193    }
194
195    #[inline(always)]
196    fn from_bytes(b: RawBytes) -> Result<Self> {
197        Ok(b.into())
198    }
199}
200
201impl KeyEnDeOrdered for String {
202    #[inline(always)]
203    fn to_bytes(&self) -> RawBytes {
204        self.as_bytes().to_vec()
205    }
206
207    #[inline(always)]
208    fn into_bytes(self) -> RawBytes {
209        self.into_bytes()
210    }
211
212    #[inline(always)]
213    fn from_slice(b: &[u8]) -> Result<Self> {
214        String::from_utf8(b.to_owned()).c(d!())
215    }
216
217    #[inline(always)]
218    fn from_bytes(b: RawBytes) -> Result<Self> {
219        String::from_utf8(b).c(d!())
220    }
221}
222
223macro_rules! impl_type {
224    ($int: ty) => {
225        impl KeyEnDeOrdered for $int {
226            #[inline(always)]
227            fn to_bytes(&self) -> RawBytes {
228                self.wrapping_sub(<$int>::MIN).to_be_bytes().to_vec()
229            }
230            #[inline(always)]
231            fn from_slice(b: &[u8]) -> Result<Self> {
232                <[u8; size_of::<$int>()]>::try_from(b)
233                    .c(d!())
234                    .map(|bytes| <$int>::from_be_bytes(bytes).wrapping_add(<$int>::MIN))
235            }
236        }
237    };
238    (@$int: ty) => {
239        impl KeyEnDeOrdered for Vec<$int> {
240            #[inline(always)]
241            fn to_bytes(&self) -> RawBytes {
242                self.iter()
243                    .map(|i| i.wrapping_sub(<$int>::MIN).to_be_bytes())
244                    .flatten()
245                    .collect::<Vec<_>>()
246            }
247            #[inline(always)]
248            fn into_bytes(self) -> RawBytes {
249                self.to_bytes()
250            }
251            #[inline(always)]
252            fn from_slice(b: &[u8]) -> Result<Self> {
253                if 0 != b.len() % size_of::<$int>() {
254                    return Err(eg!("invalid bytes"));
255                }
256                b.chunks(size_of::<$int>())
257                    .map(|i| {
258                        <[u8; size_of::<$int>()]>::try_from(i).c(d!()).map(|bytes| {
259                            <$int>::from_be_bytes(bytes).wrapping_add(<$int>::MIN)
260                        })
261                    })
262                    .collect()
263            }
264            #[inline(always)]
265            fn from_bytes(b: RawBytes) -> Result<Self> {
266                Self::from_slice(&b)
267            }
268        }
269    };
270    (^$int: ty) => {
271        impl KeyEnDeOrdered for Box<[$int]> {
272            #[inline(always)]
273            fn to_bytes(&self) -> RawBytes {
274                KeyEnDeOrdered::to_bytes(&self.to_vec())
275            }
276            #[inline(always)]
277            fn into_bytes(self) -> RawBytes {
278                KeyEnDeOrdered::into_bytes(self.to_vec())
279            }
280            #[inline(always)]
281            fn from_slice(b: &[u8]) -> Result<Self> {
282                <Vec<$int> as KeyEnDeOrdered>::from_slice(b).map(|b| b.into())
283            }
284            #[inline(always)]
285            fn from_bytes(b: RawBytes) -> Result<Self> {
286                <Vec<$int> as KeyEnDeOrdered>::from_bytes(b).map(|b| b.into())
287            }
288        }
289    };
290    ($int: ty, $siz: expr) => {
291        impl KeyEnDeOrdered for [$int; $siz] {
292            #[inline(always)]
293            fn to_bytes(&self) -> RawBytes {
294                self.iter()
295                    .map(|i| i.wrapping_sub(<$int>::MIN).to_be_bytes())
296                    .flatten()
297                    .collect::<Vec<_>>()
298            }
299            #[inline(always)]
300            fn from_slice(b: &[u8]) -> Result<Self> {
301                if 0 != b.len() % size_of::<$int>() {
302                    return Err(eg!("invalid bytes"));
303                }
304                if $siz != b.len() / size_of::<$int>() {
305                    return Err(eg!("invalid bytes"));
306                }
307                let mut res = [0; $siz];
308                b.chunks(size_of::<$int>())
309                    .enumerate()
310                    .for_each(|(idx, i)| {
311                        res[idx] = <[u8; size_of::<$int>()]>::try_from(i)
312                            .map(|bytes| {
313                                <$int>::from_be_bytes(bytes).wrapping_add(<$int>::MIN)
314                            })
315                            .unwrap();
316                    });
317                Ok(res)
318            }
319        }
320    };
321    (%$hash: ty) => {
322        impl KeyEnDeOrdered for $hash {
323            #[inline(always)]
324            fn to_bytes(&self) -> RawBytes {
325                self.as_bytes().to_vec()
326            }
327            #[inline(always)]
328            fn from_slice(b: &[u8]) -> Result<Self> {
329                if b.len() != <$hash>::len_bytes() {
330                    return Err(eg!("length mismatch"));
331                }
332                Ok(<$hash>::from_slice(b))
333            }
334        }
335    };
336    (~$big_uint: ty) => {
337        impl KeyEnDeOrdered for $big_uint {
338            #[inline(always)]
339            fn to_bytes(&self) -> RawBytes {
340                let mut r = vec![];
341                self.to_big_endian(&mut r);
342                r
343            }
344            #[inline(always)]
345            fn from_slice(b: &[u8]) -> Result<Self> {
346                Ok(<$big_uint>::from_big_endian(b))
347            }
348        }
349    };
350}
351
352macro_rules! impl_all {
353    ($t: ty) => {
354        impl_type!($t);
355    };
356    ($t: ty, $($tt: ty),+) => {
357        impl_all!($t);
358        impl_all!($($tt), +);
359    };
360    (@$t: ty) => {
361        impl_type!(@$t);
362    };
363    (@$t: ty, $(@$tt: ty),+) => {
364        impl_all!(@$t);
365        impl_all!($(@$tt), +);
366    };
367    (^$t: ty) => {
368        impl_type!(^$t);
369    };
370    (^$t: ty, $(^$tt: ty),+) => {
371        impl_all!(^$t);
372        impl_all!($(^$tt), +);
373    };
374    (%$t: ty) => {
375        impl_type!(%$t);
376    };
377    (%$t: ty, $(%$tt: ty),+) => {
378        impl_all!(%$t);
379        impl_all!($(%$tt), +);
380    };
381    (~$t: ty) => {
382        impl_type!(~$t);
383    };
384    (~$t: ty, $(~$tt: ty),+) => {
385        impl_all!(~$t);
386        impl_all!($(~$tt), +);
387    };
388}
389
390impl_all!(
391    i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize
392);
393impl_all!(
394    @i8, @i16, @i32, @i64, @i128, @isize, @u16, @u32, @u64, @u128, @usize
395);
396impl_all!(
397    ^i8, ^i16, ^i32, ^i64, ^i128, ^isize, ^u16, ^u32, ^u64, ^u128, ^usize
398);
399
400macro_rules! impl_array {
401    ($i: expr) => {
402        impl_type!(i8, $i);
403        impl_type!(i16, $i);
404        impl_type!(i32, $i);
405        impl_type!(i64, $i);
406        impl_type!(i128, $i);
407        impl_type!(isize, $i);
408        impl_type!(u8, $i);
409        impl_type!(u16, $i);
410        impl_type!(u32, $i);
411        impl_type!(u64, $i);
412        impl_type!(u128, $i);
413        impl_type!(usize, $i);
414    };
415    ($i: expr, $($ii: expr),+) => {
416        impl_array!($i);
417        impl_array!($($ii), +);
418    };
419}
420
421impl_array!(
422    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
423    24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
424    45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
425    66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
426    87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
427    106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122,
428    123, 124, 125, 126, 127, 128
429);
430
431/////////////////////////////////////////////////////////////////////////////
432/////////////////////////////////////////////////////////////////////////////