flex_page/
page_no.rs

1use std::convert::TryInto;
2use std::fmt::Debug;
3use std::hash::Hash;
4
5pub trait PageNo: Ord + Hash + Copy + Unpin + Sync + Send + Default + Debug {
6    /// Total number of bytes.
7    const SIZE: usize;
8    fn new(_: u32) -> Self;
9    fn as_u32(self) -> u32;
10    fn as_u64(self) -> u64;
11    fn to_bytes(&self) -> Vec<u8>;
12    fn from_bytes(_: &[u8]) -> Self;
13}
14macro_rules! impl_trait {
15    ($name:ident for $($t:ty:$S:expr)*) => ($(
16        impl $name for $t {
17            const SIZE: usize = $S;
18            #[inline]
19            fn new(num: u32) -> Self { num.try_into().unwrap() }
20            #[inline]
21            fn as_u32(self) -> u32 { self.into() }
22            #[inline]
23            fn as_u64(self) -> u64 { self.into() }
24            #[inline]
25            fn to_bytes(&self) -> Vec<u8> { self.to_le_bytes().to_vec() }
26            #[inline]
27            fn from_bytes(buf: &[u8]) -> Self { Self::from_le_bytes(buf.try_into().unwrap()) }
28        }
29    )*)
30}
31impl_trait!(PageNo for u8:1 u16:2 u32:4);
32
33#[repr(transparent)]
34#[derive(Hash, PartialEq, Eq, Clone, Copy, PartialOrd, Ord, Default, Debug)]
35pub struct U24(u32);
36
37impl PageNo for U24 {
38    const SIZE: usize = 3;
39
40    #[inline]
41    fn new(num: u32) -> Self {
42        assert!(num < 16777215);
43        Self(num)
44    }
45
46    #[inline]
47    fn to_bytes(&self) -> Vec<u8> {
48        let [a, b, c, _] = self.0.to_le_bytes();
49        [a, b, c].to_vec()
50    }
51
52    #[inline]
53    fn from_bytes(buf: &[u8]) -> Self {
54        Self(u32::from_le_bytes([buf[0], buf[1], buf[2], 0]))
55    }
56
57    #[inline]
58    fn as_u32(self) -> u32 {
59        self.0
60    }
61
62    #[inline]
63    fn as_u64(self) -> u64 {
64        self.0.into()
65    }
66}