1use crate::keys::KeyTrait;
2use crate::partials::vector_partial::VectorPartial;
3
4#[derive(Clone, Eq, PartialEq, PartialOrd, Ord)]
45pub struct VectorKey {
46 data: Box<[u8]>,
47}
48
49impl AsRef<[u8]> for VectorKey {
50 fn as_ref(&self) -> &[u8] {
51 &self.data
52 }
53}
54
55impl VectorKey {
56 pub fn new_from_string(s: &String) -> Self {
57 let mut data = Vec::with_capacity(s.len() + 1);
58 data.extend_from_slice(s.as_bytes());
59 data.push(0);
60 Self {
61 data: data.into_boxed_slice(),
62 }
63 }
64
65 pub fn new_from_str(s: &str) -> Self {
66 let mut data = Vec::with_capacity(s.len() + 1);
67 data.extend_from_slice(s.as_bytes());
68 data.push(0);
69 Self {
70 data: data.into_boxed_slice(),
71 }
72 }
73
74 pub fn new_from_vec(data: Vec<u8>) -> Self {
75 Self {
76 data: data.into_boxed_slice(),
77 }
78 }
79
80 pub fn to_be_u64(&self) -> u64 {
81 debug_assert!(self.data.len() >= 8, "data length is less than 8 bytes");
83 let mut arr = [0; 8];
85 arr[8 - self.data.len()..].copy_from_slice(&self.data[..self.data.len()]);
86 u64::from_be_bytes(arr)
87 }
88}
89
90impl KeyTrait for VectorKey {
91 type PartialType = VectorPartial;
92 const MAXIMUM_SIZE: Option<usize> = None;
93
94 fn extend_from_partial(&self, partial: &Self::PartialType) -> Self {
95 let mut v = self.data.to_vec();
96 v.extend_from_slice(partial.to_slice());
97 Self {
98 data: v.into_boxed_slice(),
99 }
100 }
101
102 fn truncate(&self, at_depth: usize) -> Self {
103 let mut v = self.data.to_vec();
104 v.truncate(at_depth);
105 Self {
106 data: v.into_boxed_slice(),
107 }
108 }
109
110 fn new_from_slice(data: &[u8]) -> Self {
111 let data = Vec::from(data);
112 Self {
113 data: data.into_boxed_slice(),
114 }
115 }
116 fn at(&self, pos: usize) -> u8 {
117 self.data[pos]
118 }
119
120 fn length_at(&self, at_depth: usize) -> usize {
121 self.data.len() - at_depth
122 }
123
124 fn to_partial(&self, at_depth: usize) -> VectorPartial {
125 VectorPartial::from_slice(&self.data[at_depth..])
126 }
127
128 fn matches_slice(&self, slice: &[u8]) -> bool {
129 self.data.len() == slice.len() && &self.data[..] == slice
130 }
131
132 fn new_from_partial(partial: &Self::PartialType) -> Self {
133 let data = Vec::from(partial.to_slice());
134 Self {
135 data: data.into_boxed_slice(),
136 }
137 }
138}
139
140impl From<String> for VectorKey {
141 fn from(data: String) -> Self {
142 Self::new_from_string(&data)
143 }
144}
145impl From<&String> for VectorKey {
146 fn from(data: &String) -> Self {
147 Self::new_from_string(data)
148 }
149}
150impl From<&str> for VectorKey {
151 fn from(data: &str) -> Self {
152 Self::new_from_str(data)
153 }
154}
155macro_rules! impl_from_unsigned {
156 ( $($t:ty),* ) => {
157 $(
158 impl From< $t > for VectorKey
159 {
160 fn from(data: $t) -> Self {
161 VectorKey::new_from_slice(&data.to_be_bytes())
162 }
163 }
164 impl From< &$t > for VectorKey
165 {
166 fn from(data: &$t) -> Self {
167 (*data).into()
168 }
169 }
170 ) *
171 }
172}
173impl_from_unsigned!(u8, u16, u32, u64, usize, u128);
174
175impl From<i8> for VectorKey {
176 fn from(val: i8) -> Self {
177 let v: u8 = val as u8;
179 let j = v ^ 0x80; let v = vec![j];
181 VectorKey::new_from_vec(v)
182 }
183}
184
185macro_rules! impl_from_signed {
186 ( $t:ty, $tu:ty ) => {
187 impl From<$t> for VectorKey {
188 fn from(val: $t) -> Self {
189 let v: $tu = val as $tu;
191 let sign_bit = 1 << (std::mem::size_of::<$tu>() * 8 - 1);
192 let j = v ^ sign_bit;
193 VectorKey::new_from_slice(&j.to_be_bytes())
194 }
195 }
196
197 impl From<&$t> for VectorKey {
198 fn from(val: &$t) -> Self {
199 (*val).into()
200 }
201 }
202 };
203}
204
205impl_from_signed!(i16, u16);
206impl_from_signed!(i32, u32);
207impl_from_signed!(i64, u64);
208impl_from_signed!(i128, u128);
209impl_from_signed!(isize, usize);
210
211#[cfg(test)]
212mod test {
213 use crate::keys::KeyTrait;
214 use crate::keys::vector_key::VectorKey;
215 use crate::partials::vector_partial::VectorPartial;
216
217 #[test]
218 fn make_extend_truncate() {
219 let k = VectorKey::new_from_slice(b"hel");
220 let p = VectorPartial::from_slice(b"lo");
221 let k2 = k.extend_from_partial(&p);
222 assert!(k2.matches_slice(b"hello"));
223 let k3 = k2.truncate(3);
224 assert!(k3.matches_slice(b"hel"));
225 }
226
227 #[test]
228 fn from_to_u64() {
229 let k: VectorKey = 123u64.into();
230 assert_eq!(k.to_be_u64(), 123u64);
231
232 let k: VectorKey = 1u64.into();
233 assert_eq!(k.to_be_u64(), 1u64);
234
235 let k: VectorKey = 123213123123123u64.into();
236 assert_eq!(k.to_be_u64(), 123213123123123u64);
237 }
238}