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);