willow_data_model/groupings/keylike.rs
1use crate::paths::*;
2
3/// A keylike value is one that can be used to uniquely identify an [Entry](https://willowprotocol.org/specs/data-model/index.html#Entry) within a [namespace](https://willowprotocol.org/specs/data-model/index.html#namespace)-specific [store](https://willowprotocol.org/specs/data-model/index.html#store).
4///
5/// A [subspace_id](https://willowprotocol.org/specs/data-model/index.html#entry_subspace_id) and a [path](https://willowprotocol.org/specs/data-model/index.html#entry_path) together uniquely identify an entry in a namespace, because between any two non-equal entries with of equal [subspace_id](https://willowprotocol.org/specs/data-model/index.html#entry_subspace_id), [path](https://willowprotocol.org/specs/data-model/index.html#entry_path), and [namespace_id](https://willowprotocol.org/specs/data-model/index.html#entry_namespace_id), one would overwrite the other.
6pub trait Keylike<const MCL: usize, const MCC: usize, const MPL: usize, S> {
7 /// Returns the [subspace_id](https://willowprotocol.org/specs/data-model/index.html#entry_subspace_id) of `self`.
8 fn wdm_subspace_id(&self) -> &S;
9
10 /// Returns the [path](https://willowprotocol.org/specs/data-model/index.html#entry_path) of `self`.
11 fn wdm_path(&self) -> &Path<MCL, MCC, MPL>;
12}
13
14impl<const MCL: usize, const MCC: usize, const MPL: usize, S> Keylike<MCL, MCC, MPL, S>
15 for (S, Path<MCL, MCC, MPL>)
16{
17 fn wdm_subspace_id(&self) -> &S {
18 &self.0
19 }
20
21 fn wdm_path(&self) -> &Path<MCL, MCC, MPL> {
22 &self.1
23 }
24}
25
26/// Methods for working with [`Keylikes`](Keylike).
27///
28/// This trait is automatically implemented by all types implementing [`Keylike`].
29pub trait KeylikeExt<const MCL: usize, const MCC: usize, const MPL: usize, S>:
30 Keylike<MCL, MCC, MPL, S>
31{
32 /// Returns whether `self` and `other` describe equal keys, i.e., whether their [subspace ids](Keylike::wdm_subspace_id) and [paths](Keylike::wdm_path) are both equal.
33 ///
34 /// # Examples
35 ///
36 /// ```
37 /// use willow_data_model::prelude::*;
38 ///
39 /// assert!(("alfie", Path::<4, 4, 4>::new()).wdm_key_eq(&("alfie", Path::<4, 4, 4>::new())));
40 /// assert!(!("alfie", Path::<4, 4, 4>::new()).wdm_key_eq(&("betty", Path::<4, 4, 4>::new())));
41 /// ```
42 fn wdm_key_eq<OtherKey>(&self, other: &OtherKey) -> bool
43 where
44 OtherKey: Keylike<MCL, MCC, MPL, S>,
45 S: PartialEq,
46 {
47 self.wdm_subspace_id() == other.wdm_subspace_id() && self.wdm_path() == other.wdm_path()
48 }
49
50 /// Returns whether `self` and `other` describe non-equal keys, i.e., whether their [subspace ids](Keylike::wdm_subspace_id) and [paths](Keylike::wdm_path) are not both equal.
51 ///
52 /// # Examples
53 ///
54 /// ```
55 /// use willow_data_model::prelude::*;
56 ///
57 /// assert!(!("alfie", Path::<4, 4, 4>::new()).wdm_key_ne(&("alfie", Path::<4, 4, 4>::new())));
58 /// assert!(("alfie", Path::<4, 4, 4>::new()).wdm_key_ne(&("betty", Path::<4, 4, 4>::new())));
59 /// ```
60 fn wdm_key_ne<OtherKey>(&self, other: &OtherKey) -> bool
61 where
62 OtherKey: Keylike<MCL, MCC, MPL, S>,
63 S: PartialEq,
64 {
65 self.wdm_subspace_id() != other.wdm_subspace_id() || self.wdm_path() != other.wdm_path()
66 }
67}
68
69impl<const MCL: usize, const MCC: usize, const MPL: usize, S, T> KeylikeExt<MCL, MCC, MPL, S> for T where
70 T: Keylike<MCL, MCC, MPL, S> + ?Sized
71{
72}