1use cosmwasm_std::{storage_keys::namespace_with_key, Addr};
2
3use crate::de::KeyDeserialize;
4use crate::int_key::IntKey;
5
6#[derive(Debug)]
7pub enum Key<'a> {
8 Ref(&'a [u8]),
9 Val8([u8; 1]),
10 Val16([u8; 2]),
11 Val32([u8; 4]),
12 Val64([u8; 8]),
13 Val128([u8; 16]),
14}
15
16impl<'a> AsRef<[u8]> for Key<'a> {
17 fn as_ref(&self) -> &[u8] {
18 match self {
19 Key::Ref(r) => r,
20 Key::Val8(v) => v,
21 Key::Val16(v) => v,
22 Key::Val32(v) => v,
23 Key::Val64(v) => v,
24 Key::Val128(v) => v,
25 }
26 }
27}
28
29impl<'a> PartialEq<&[u8]> for Key<'a> {
30 fn eq(&self, other: &&[u8]) -> bool {
31 self.as_ref() == *other
32 }
33}
34
35pub trait PrimaryKey<'a>: Clone {
55 type Prefix: Prefixer<'a>;
58 type SubPrefix: Prefixer<'a>;
59
60 type Suffix: KeyDeserialize;
63 type SuperSuffix: KeyDeserialize;
64
65 fn key(&self) -> Vec<Key>;
67
68 fn joined_key(&self) -> Vec<u8> {
69 let keys = self.key();
70 let l = keys.len();
71 namespace_with_key(
72 &keys[0..l - 1].iter().map(Key::as_ref).collect::<Vec<_>>(),
73 keys[l - 1].as_ref(),
74 )
75 }
76
77 fn joined_extra_key(&self, key: &[u8]) -> Vec<u8> {
78 let keys = self.key();
79 namespace_with_key(&keys.iter().map(Key::as_ref).collect::<Vec<_>>(), key)
80 }
81}
82
83impl<'a> PrimaryKey<'a> for () {
85 type Prefix = Self;
86 type SubPrefix = Self;
87 type Suffix = Self;
88 type SuperSuffix = Self;
89
90 fn key(&self) -> Vec<Key> {
91 vec![]
92 }
93}
94
95impl<'a> PrimaryKey<'a> for &'a [u8] {
96 type Prefix = ();
97 type SubPrefix = ();
98 type Suffix = Self;
99 type SuperSuffix = Self;
100
101 fn key(&self) -> Vec<Key> {
102 vec![Key::Ref(self)]
104 }
105}
106
107impl<'a, const N: usize> PrimaryKey<'a> for [u8; N] {
108 type Prefix = ();
109 type SubPrefix = ();
110 type Suffix = Self;
111 type SuperSuffix = Self;
112
113 fn key(&self) -> Vec<Key> {
114 vec![Key::Ref(self.as_slice())]
116 }
117}
118
119impl<'a> PrimaryKey<'a> for &'a str {
121 type Prefix = ();
122 type SubPrefix = ();
123 type Suffix = Self;
124 type SuperSuffix = Self;
125
126 fn key(&self) -> Vec<Key> {
127 vec![Key::Ref(self.as_bytes())]
129 }
130}
131
132impl<'a, T: PrimaryKey<'a> + Prefixer<'a> + KeyDeserialize, U: PrimaryKey<'a> + KeyDeserialize>
134 PrimaryKey<'a> for (T, U)
135{
136 type Prefix = T;
137 type SubPrefix = ();
138 type Suffix = U;
139 type SuperSuffix = Self;
140
141 fn key(&self) -> Vec<Key> {
142 let mut keys = self.0.key();
143 keys.extend(self.1.key());
144 keys
145 }
146}
147
148impl<'a, T> PrimaryKey<'a> for &'a T
150where
151 T: PrimaryKey<'a>,
152{
153 type Prefix = <T as PrimaryKey<'a>>::Prefix;
154 type SubPrefix = <T as PrimaryKey<'a>>::SubPrefix;
155 type Suffix = T::Suffix;
156 type SuperSuffix = T::SuperSuffix;
157
158 fn key(&self) -> Vec<Key> {
159 <T as PrimaryKey<'a>>::key(self)
160 }
161}
162
163impl<
165 'a,
166 T: PrimaryKey<'a> + Prefixer<'a>,
167 U: PrimaryKey<'a> + Prefixer<'a> + KeyDeserialize,
168 V: PrimaryKey<'a> + KeyDeserialize,
169 > PrimaryKey<'a> for (T, U, V)
170{
171 type Prefix = (T, U);
172 type SubPrefix = T;
173 type Suffix = V;
174 type SuperSuffix = (U, V);
175
176 fn key(&self) -> Vec<Key> {
177 let mut keys = self.0.key();
178 keys.extend(self.1.key());
179 keys.extend(self.2.key());
180 keys
181 }
182}
183
184pub trait Prefixer<'a> {
185 fn prefix(&self) -> Vec<Key>;
187
188 fn joined_prefix(&self) -> Vec<u8> {
189 let prefixes = self.prefix();
190 namespace_with_key(&prefixes.iter().map(Key::as_ref).collect::<Vec<_>>(), &[])
191 }
192}
193
194impl<'a> Prefixer<'a> for () {
195 fn prefix(&self) -> Vec<Key> {
196 vec![]
197 }
198}
199
200impl<'a> Prefixer<'a> for &'a [u8] {
201 fn prefix(&self) -> Vec<Key> {
202 vec![Key::Ref(self)]
203 }
204}
205
206impl<'a, T: Prefixer<'a>, U: Prefixer<'a>> Prefixer<'a> for (T, U) {
207 fn prefix(&self) -> Vec<Key> {
208 let mut res = self.0.prefix();
209 res.extend(self.1.prefix());
210 res
211 }
212}
213
214impl<'a, T: Prefixer<'a>, U: Prefixer<'a>, V: Prefixer<'a>> Prefixer<'a> for (T, U, V) {
215 fn prefix(&self) -> Vec<Key> {
216 let mut res = self.0.prefix();
217 res.extend(self.1.prefix());
218 res.extend(self.2.prefix());
219 res
220 }
221}
222
223impl<'a, T> Prefixer<'a> for &'a T
224where
225 T: Prefixer<'a>,
226{
227 fn prefix(&self) -> Vec<Key> {
228 <T as Prefixer<'a>>::prefix(self)
229 }
230}
231
232impl<'a> Prefixer<'a> for &'a str {
234 fn prefix(&self) -> Vec<Key> {
235 vec![Key::Ref(self.as_bytes())]
236 }
237}
238
239impl<'a> PrimaryKey<'a> for Vec<u8> {
240 type Prefix = ();
241 type SubPrefix = ();
242 type Suffix = Self;
243 type SuperSuffix = Self;
244
245 fn key(&self) -> Vec<Key> {
246 vec![Key::Ref(self)]
247 }
248}
249
250impl<'a> Prefixer<'a> for Vec<u8> {
251 fn prefix(&self) -> Vec<Key> {
252 vec![Key::Ref(self.as_ref())]
253 }
254}
255
256impl<'a> PrimaryKey<'a> for String {
257 type Prefix = ();
258 type SubPrefix = ();
259 type Suffix = Self;
260 type SuperSuffix = Self;
261
262 fn key(&self) -> Vec<Key> {
263 vec![Key::Ref(self.as_bytes())]
264 }
265}
266
267impl<'a> Prefixer<'a> for String {
268 fn prefix(&self) -> Vec<Key> {
269 vec![Key::Ref(self.as_bytes())]
270 }
271}
272
273impl<'a> PrimaryKey<'a> for Addr {
275 type Prefix = ();
276 type SubPrefix = ();
277 type Suffix = Self;
278 type SuperSuffix = Self;
279
280 fn key(&self) -> Vec<Key> {
281 vec![Key::Ref(self.as_bytes())]
283 }
284}
285
286impl<'a> Prefixer<'a> for Addr {
287 fn prefix(&self) -> Vec<Key> {
288 vec![Key::Ref(self.as_bytes())]
289 }
290}
291
292macro_rules! integer_key {
293 (for $($t:ty, $v:tt),+) => {
294 $(impl<'a> PrimaryKey<'a> for $t {
295 type Prefix = ();
296 type SubPrefix = ();
297 type Suffix = Self;
298 type SuperSuffix = Self;
299
300 fn key(&self) -> Vec<Key> {
301 vec![Key::$v(self.to_cw_bytes())]
302 }
303 })*
304 }
305}
306
307integer_key!(for i8, Val8, u8, Val8, i16, Val16, u16, Val16, i32, Val32, u32, Val32, i64, Val64, u64, Val64, i128, Val128, u128, Val128);
308
309macro_rules! integer_prefix {
310 (for $($t:ty, $v:tt),+) => {
311 $(impl<'a> Prefixer<'a> for $t {
312 fn prefix(&self) -> Vec<Key> {
313 vec![Key::$v(self.to_cw_bytes())]
314 }
315 })*
316 }
317}
318
319integer_prefix!(for i8, Val8, u8, Val8, i16, Val16, u16, Val16, i32, Val32, u32, Val32, i64, Val64, u64, Val64, i128, Val128, u128, Val128);
320
321#[cfg(test)]
322mod test {
323 use cosmwasm_std::{Uint256, Uint512};
324
325 use super::*;
326
327 #[test]
328 fn naked_8key_works() {
329 let k: u8 = 42u8;
330 let path = k.key();
331 assert_eq!(1, path.len());
332 assert_eq!(42u8.to_cw_bytes(), path[0].as_ref());
333
334 let k: i8 = 42i8;
335 let path = k.key();
336 assert_eq!(1, path.len());
337 assert_eq!(42i8.to_cw_bytes(), path[0].as_ref());
338 }
339
340 #[test]
341 fn naked_16key_works() {
342 let k: u16 = 4242u16;
343 let path = k.key();
344 assert_eq!(1, path.len());
345 assert_eq!(4242u16.to_cw_bytes(), path[0].as_ref());
346
347 let k: i16 = 4242i16;
348 let path = k.key();
349 assert_eq!(1, path.len());
350 assert_eq!(4242i16.to_cw_bytes(), path[0].as_ref());
351 }
352
353 #[test]
354 fn naked_32key_works() {
355 let k: u32 = 4242u32;
356 let path = k.key();
357 assert_eq!(1, path.len());
358 assert_eq!(4242u32.to_cw_bytes(), path[0].as_ref());
359
360 let k: i32 = 4242i32;
361 let path = k.key();
362 assert_eq!(1, path.len());
363 assert_eq!(4242i32.to_cw_bytes(), path[0].as_ref());
364 }
365
366 #[test]
367 fn naked_64key_works() {
368 let k: u64 = 4242u64;
369 let path = k.key();
370 assert_eq!(1, path.len());
371 assert_eq!(4242u64.to_cw_bytes(), path[0].as_ref());
372
373 let k: i64 = 4242i64;
374 let path = k.key();
375 assert_eq!(1, path.len());
376 assert_eq!(4242i64.to_cw_bytes(), path[0].as_ref());
377 }
378
379 #[test]
380 fn naked_128key_works() {
381 let k: u128 = 4242u128;
382 let path = k.key();
383 assert_eq!(1, path.len());
384 assert_eq!(4242u128.to_cw_bytes(), path[0].as_ref());
385
386 let k: i128 = 4242i128;
387 let path = k.key();
388 assert_eq!(1, path.len());
389 assert_eq!(4242i128.to_cw_bytes(), path[0].as_ref());
390 }
391
392 #[test]
393 fn str_key_works() {
394 type K<'a> = &'a str;
395
396 let k: K = "hello";
397 let path = k.key();
398 assert_eq!(1, path.len());
399 assert_eq!(b"hello", path[0].as_ref());
400
401 let joined = k.joined_key();
402 assert_eq!(joined, b"hello")
403 }
404
405 #[test]
406 fn string_key_works() {
407 type K = String;
408
409 let k: K = "hello".to_string();
410 let path = k.key();
411 assert_eq!(1, path.len());
412 assert_eq!(b"hello", path[0].as_ref());
413
414 let joined = k.joined_key();
415 assert_eq!(joined, b"hello")
416 }
417
418 #[test]
419 fn fixed_size_bytes_key_works() {
420 type K = [u8; 32];
421
422 let k: K = Uint256::MAX.to_be_bytes();
423 let path = k.key();
424 assert_eq!(1, path.len());
425 assert_eq!(k, path[0].as_ref());
426
427 let joined = k.joined_key();
428 assert_eq!(joined, k);
429
430 type K2<'a> = &'a [u8; 64];
432
433 let k: K2 = &Uint512::MAX.to_be_bytes();
434 let path = k.key();
435 assert_eq!(1, path.len());
436 assert_eq!(k, path[0].as_ref());
437
438 let joined = k.joined_key();
439 assert_eq!(joined, k);
440 }
441
442 #[test]
443 fn nested_str_key_works() {
444 type K<'a> = (&'a str, &'a [u8]);
445
446 let k: K = ("hello", b"world");
447 let path = k.key();
448 assert_eq!(2, path.len());
449 assert_eq!(b"hello", path[0].as_ref());
450 assert_eq!(b"world", path[1].as_ref());
451 }
452
453 #[test]
454 fn composite_byte_key() {
455 let k: (&[u8], &[u8]) = ("foo".as_bytes(), b"bar");
456 let path = k.key();
457 assert_eq!(2, path.len());
458 assert_eq!(path, vec!["foo".as_bytes(), b"bar"],);
459 }
460
461 #[test]
462 fn naked_composite_int_key() {
463 let k: (u32, u64) = (123, 87654);
464 let path = k.key();
465 assert_eq!(2, path.len());
466 assert_eq!(4, path[0].as_ref().len());
467 assert_eq!(8, path[1].as_ref().len());
468 assert_eq!(path[0].as_ref(), 123u32.to_cw_bytes());
469 assert_eq!(path[1].as_ref(), 87654u64.to_cw_bytes());
470 }
471
472 #[test]
473 fn nested_composite_keys() {
474 let first: &[u8] = b"foo";
476 let k: ((&[u8], &[u8]), &[u8]) = ((first, b"bar"), b"zoom");
478 let path = k.key();
479 assert_eq!(3, path.len());
480 assert_eq!(path, vec![first, b"bar", b"zoom"]);
481
482 let dir = k.0.prefix();
484 assert_eq!(2, dir.len());
485 assert_eq!(dir, vec![first, b"bar"]);
486 }
487
488 #[test]
489 fn naked_8bit_prefixes() {
490 let pair: (u8, &[u8]) = (123, b"random");
491 let one: Vec<u8> = vec![123];
492 let two: Vec<u8> = b"random".to_vec();
493 assert_eq!(pair.prefix(), vec![one.as_slice(), two.as_slice()]);
494
495 let pair: (i8, &[u8]) = (123, b"random");
496 let one: Vec<u8> = vec![123 ^ 0x80];
498 let two: Vec<u8> = b"random".to_vec();
499 assert_eq!(pair.prefix(), vec![one.as_slice(), two.as_slice()]);
500 }
501
502 #[test]
503 fn naked_16bit_prefixes() {
504 let pair: (u16, &[u8]) = (12345, b"random");
505 let one: Vec<u8> = vec![48, 57];
506 let two: Vec<u8> = b"random".to_vec();
507 assert_eq!(pair.prefix(), vec![one.as_slice(), two.as_slice()]);
508
509 let pair: (i16, &[u8]) = (12345, b"random");
510 let one: Vec<u8> = vec![48 ^ 0x80, 57];
512 let two: Vec<u8> = b"random".to_vec();
513 assert_eq!(pair.prefix(), vec![one.as_slice(), two.as_slice()]);
514 }
515
516 #[test]
517 fn naked_64bit_prefixes() {
518 let pair: (u64, &[u8]) = (12345, b"random");
519 let one: Vec<u8> = vec![0, 0, 0, 0, 0, 0, 48, 57];
520 let two: Vec<u8> = b"random".to_vec();
521 assert_eq!(pair.prefix(), vec![one.as_slice(), two.as_slice()]);
522
523 let pair: (i64, &[u8]) = (12345, b"random");
524 #[allow(clippy::identity_op)]
526 let one: Vec<u8> = vec![0 ^ 0x80, 0, 0, 0, 0, 0, 48, 57];
527 let two: Vec<u8> = b"random".to_vec();
528 assert_eq!(pair.prefix(), vec![one.as_slice(), two.as_slice()]);
529 }
530
531 #[test]
532 fn naked_proper_prefixes() {
533 let pair: (u32, &[u8]) = (12345, b"random");
534 let one: Vec<u8> = vec![0, 0, 48, 57];
535 let two: Vec<u8> = b"random".to_vec();
536 assert_eq!(pair.prefix(), vec![one.as_slice(), two.as_slice()]);
537
538 let triple: (&str, u32, &[u8]) = ("begin", 12345, b"end");
539 let one: Vec<u8> = b"begin".to_vec();
540 let two: Vec<u8> = vec![0, 0, 48, 57];
541 let three: Vec<u8> = b"end".to_vec();
542 assert_eq!(
543 triple.prefix(),
544 vec![one.as_slice(), two.as_slice(), three.as_slice()]
545 );
546
547 let owned_triple: (String, u32, Vec<u8>) = ("begin".to_string(), 12345, b"end".to_vec());
549 assert_eq!(
550 owned_triple.prefix(),
551 vec![one.as_slice(), two.as_slice(), three.as_slice()]
552 );
553 }
554}