stupid_simple_kv/keys/
key_decoder.rs

1use crate::keys::key_segment::KeySegmentTag;
2use crate::{KvError, KvKey};
3
4pub struct KeyDecoder<'a> {
5    rem: &'a [u8],
6}
7
8impl<'a> KeyDecoder<'a> {
9    pub fn new(rem: &'a [u8]) -> Self {
10        Self { rem }
11    }
12
13    pub fn next_str(&mut self) -> Option<&'a str> {
14        if self.rem.len() < 9 || self.rem[0] != KeySegmentTag::String as u8 {
15            return None;
16        }
17
18        let len = usize::from_be_bytes(self.rem[1..9].try_into().ok()?);
19        if self.rem.len() < 9 + len {
20            return None;
21        }
22
23        let out = str::from_utf8(&self.rem[9..len + 9]).ok()?;
24        self.rem = &self.rem[9 + len..];
25        Some(out)
26    }
27
28    pub fn next_bool(&mut self) -> Option<bool> {
29        if self.rem.len() < 2 || self.rem[0] != KeySegmentTag::Bool as u8 {
30            return None;
31        }
32        let byte = self.rem[1];
33        self.rem = &self.rem[2..];
34        Some(byte != 0)
35    }
36
37    pub fn next_i64(&mut self) -> Option<i64> {
38        if self.rem.len() < 9 || self.rem[0] != KeySegmentTag::I64 as u8 {
39            return None;
40        }
41        let bytes: [u8; 8] = self.rem[1..9].try_into().ok()?;
42        let int = i64::from_be_bytes(bytes);
43        self.rem = &self.rem[9..];
44        Some(int)
45    }
46
47    pub fn next_u64(&mut self) -> Option<u64> {
48        if self.rem.len() < 9 || self.rem[0] != KeySegmentTag::U64 as u8 {
49            return None;
50        }
51        let bytes: [u8; 8] = self.rem[1..9].try_into().ok()?;
52        let num = u64::from_be_bytes(bytes);
53        self.rem = &self.rem[9..];
54        Some(num)
55    }
56}
57
58pub trait FromKvKey<'a>: Sized {
59    fn from_kv_key(decoder: &mut KeyDecoder<'a>) -> Option<Self>;
60}
61
62impl<'a> FromKvKey<'a> for i64 {
63    fn from_kv_key(decoder: &mut KeyDecoder<'a>) -> Option<Self> {
64        decoder.next_i64()
65    }
66}
67
68impl<'a> FromKvKey<'a> for u64 {
69    fn from_kv_key(decoder: &mut KeyDecoder<'a>) -> Option<Self> {
70        decoder.next_u64()
71    }
72}
73
74impl<'a> FromKvKey<'a> for bool {
75    fn from_kv_key(decoder: &mut KeyDecoder<'a>) -> Option<Self> {
76        decoder.next_bool()
77    }
78}
79
80impl<'a> FromKvKey<'a> for &'a str {
81    fn from_kv_key(decoder: &mut KeyDecoder<'a>) -> Option<Self> {
82        decoder.next_str()
83    }
84}
85
86impl<'a> FromKvKey<'a> for String {
87    fn from_kv_key(decoder: &mut KeyDecoder<'a>) -> Option<Self> {
88        decoder.next_str().map(String::from)
89    }
90}
91
92macro_rules! impl_key_decode_for_tuple {
93    ($($name:ident),+) => {
94        impl<'a, $($name),+> FromKvKey<'a> for ($($name,)+)
95        where
96            $($name: FromKvKey<'a>),+
97        {
98            fn from_kv_key(decoder: &mut KeyDecoder<'a>) -> Option<Self> {
99                Some((
100                    $(
101                        <$name as FromKvKey>::from_kv_key(decoder)?,
102                    )+
103                ))
104            }
105        }
106    };
107}
108
109impl_key_decode_for_tuple!(A);
110impl_key_decode_for_tuple!(A, B);
111impl_key_decode_for_tuple!(A, B, C);
112impl_key_decode_for_tuple!(A, B, C, D);
113impl_key_decode_for_tuple!(A, B, C, D, E);
114impl_key_decode_for_tuple!(A, B, C, D, E, F);
115impl_key_decode_for_tuple!(A, B, C, D, E, F, G);
116impl_key_decode_for_tuple!(A, B, C, D, E, F, G, H);
117impl_key_decode_for_tuple!(A, B, C, D, E, F, G, H, I);
118
119macro_rules! impl_kv_key_try_from_tuple {
120    ($($name:ident),+) => {
121        impl<$($name: for<'a> FromKvKey<'a>),+> TryFrom<KvKey> for ($($name,)+) {
122            type Error = KvError;
123            fn try_from(key: KvKey) -> Result<Self, Self::Error> {
124                let mut decoder = KeyDecoder::new(&key.0);
125                $(
126                    #[allow(non_snake_case)]
127                    let $name = <$name as FromKvKey>::from_kv_key(&mut decoder)
128                        .ok_or_else(|| KvError::KeyDecodeError(
129                            format!("Failed to decode key segment \"{}\"", stringify!($name)))
130                        )?;
131                )+
132                Ok(($($name,)+))
133            }
134        }
135    }
136}
137
138impl_kv_key_try_from_tuple!(A);
139impl_kv_key_try_from_tuple!(A, B);
140impl_kv_key_try_from_tuple!(A, B, C);
141impl_kv_key_try_from_tuple!(A, B, C, D);
142impl_kv_key_try_from_tuple!(A, B, C, D, E);
143impl_kv_key_try_from_tuple!(A, B, C, D, E, F);
144impl_kv_key_try_from_tuple!(A, B, C, D, E, F, G);
145impl_kv_key_try_from_tuple!(A, B, C, D, E, F, G, H);
146impl_kv_key_try_from_tuple!(A, B, C, D, E, F, G, H, I);