stupid_simple_kv/keys/
mod.rs1use key_segment::KeySegment;
2pub mod display;
3mod key_decoder;
4mod key_segment;
5
6#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Debug)]
8pub struct KvKey(pub(crate) Vec<u8>);
9
10impl Default for KvKey {
11 fn default() -> Self {
12 Self::new()
13 }
14}
15
16impl KvKey {
17 pub fn new() -> Self {
18 Self(Vec::with_capacity(128))
19 }
20
21 pub fn push(&mut self, part: &dyn KeySegment) {
22 part.encode_into(&mut self.0);
23 }
24
25 pub fn starts_with(&self, key: &KvKey) -> bool {
26 self.0.starts_with(&key.0)
27 }
28
29 pub fn successor(&self) -> Option<KvKey> {
32 let mut bytes = self.0.clone();
33 for i in (0..bytes.len()).rev() {
34 if bytes[i] != 0xFF {
35 bytes[i] += 1;
36 bytes.truncate(i + 1); return Some(KvKey(bytes));
38 }
39 }
41 None
43 }
44}
45
46pub trait IntoKey {
50 fn to_key(&self) -> KvKey;
51}
52
53impl IntoKey for u64 {
54 fn to_key(&self) -> KvKey {
55 let mut key = KvKey::new();
56 key.push(self);
57 key
58 }
59}
60
61impl IntoKey for i64 {
62 fn to_key(&self) -> KvKey {
63 let mut key = KvKey::new();
64 key.push(self);
65 key
66 }
67}
68
69impl IntoKey for String {
70 fn to_key(&self) -> KvKey {
71 let mut key = KvKey::new();
72 key.push(self);
73 key
74 }
75}
76
77impl IntoKey for bool {
78 fn to_key(&self) -> KvKey {
79 let mut key = KvKey::new();
80 key.push(self);
81 key
82 }
83}
84
85impl IntoKey for &str {
86 fn to_key(&self) -> KvKey {
87 let mut key = KvKey::new();
88 key.push(self);
89 key
90 }
91}
92
93impl IntoKey for KvKey {
94 fn to_key(&self) -> KvKey {
95 self.clone()
96 }
97}
98
99#[cfg(test)]
100mod tests {
101 use crate::{KvResult, keys::IntoKey};
102
103 #[test]
110 fn roundtrip_one_tuple() -> KvResult<()> {
111 let tup = (42u64,);
112 let key = tup.to_key();
113 let out: (u64,) = key.try_into()?;
114 assert_eq!(tup, out);
115 Ok(())
116 }
117
118 #[test]
119 fn roundtrip_simple_tuple() -> KvResult<()> {
120 let tup = (1234u64, String::from("hello"));
121 let key = tup.clone().to_key();
122 let out: (u64, String) = key.try_into()?;
123 assert_eq!(tup, out);
124 Ok(())
125 }
126
127 #[test]
128 fn roundtrip_longer_tuple() -> KvResult<()> {
129 let tup = (19u64, -5i64, "foo", true, false);
130 let key = tup.clone().to_key();
131 let out: (u64, i64, String, bool, bool) = key.try_into()?;
132 assert_eq!((tup.0, tup.1, tup.2.to_owned(), tup.3, tup.4), out);
133 Ok(())
134 }
135
136 #[test]
137 fn roundtrip_tuple_tryfrom() -> KvResult<()> {
138 let tup = (7u64, "hello world", true);
139 let key = tup.clone().to_key();
140 let out: (u64, String, bool) = key.try_into()?;
141 assert_eq!((tup.0, tup.1.to_owned(), tup.2), out);
142 Ok(())
143 }
144
145 #[test]
146 fn decode_error_wrong_type() -> KvResult<()> {
147 let tup = (237u64, false);
148 let key = tup.to_key();
149 let out: KvResult<(bool, u64)> = key.try_into();
151 assert!(out.is_err());
152 Ok(())
153 }
154
155 #[test]
156 fn decode_error_wrong_length() -> KvResult<()> {
157 let tup = (55u64, "xyz");
158 let key = tup.to_key();
159 let out: KvResult<(u64, String, bool)> = key.try_into();
161 assert!(out.is_err());
162 Ok(())
163 }
164
165 #[test]
166 fn roundtrip_with_strings() -> KvResult<()> {
167 let tup = (999u64, "potato", "apple", true);
168 let key = tup.clone().to_key();
169 let out: (u64, String, String, bool) = key.try_into()?;
170 assert_eq!((tup.0, tup.1.to_owned(), tup.2.to_owned(), tup.3), out);
171 Ok(())
172 }
173
174 #[test]
175 fn roundtrip_false_bool() -> KvResult<()> {
176 let tup = (0u64, false, "z");
177 let key = tup.clone().to_key();
178 let out: (u64, bool, String) = key.try_into()?;
179 assert_eq!((tup.0, tup.1, tup.2.to_owned()), out);
180 Ok(())
181 }
182}