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 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}