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.
6///
7/// This trait does not include the namespace id; we assume that entry storage is separated by namespace from the get-go.
8pub trait Keylike<const MCL: usize, const MCC: usize, const MPL: usize, S> {
9    /// Returns the [subspace_id](https://willowprotocol.org/specs/data-model/index.html#entry_subspace_id) of `self`.
10    fn wdm_subspace_id(&self) -> &S;
11
12    /// Returns the [path](https://willowprotocol.org/specs/data-model/index.html#entry_path) of `self`.
13    fn wdm_path(&self) -> &Path<MCL, MCC, MPL>;
14}
15
16impl<const MCL: usize, const MCC: usize, const MPL: usize, S> Keylike<MCL, MCC, MPL, S>
17    for (S, Path<MCL, MCC, MPL>)
18{
19    fn wdm_subspace_id(&self) -> &S {
20        &self.0
21    }
22
23    fn wdm_path(&self) -> &Path<MCL, MCC, MPL> {
24        &self.1
25    }
26}
27
28/// Methods for working with [`Keylikes`](Keylike).
29///
30/// This trait is automatically implemented by all types implementing [`Keylike`].
31pub trait KeylikeExt<const MCL: usize, const MCC: usize, const MPL: usize, S>:
32    Keylike<MCL, MCC, MPL, S>
33{
34    /// 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.
35    ///
36    /// # Examples
37    ///
38    /// ```
39    /// use willow_data_model::prelude::*;
40    ///
41    /// assert!(("alfie", Path::<4, 4, 4>::new()).wdm_key_eq(&("alfie", Path::<4, 4, 4>::new())));
42    /// assert!(!("alfie", Path::<4, 4, 4>::new()).wdm_key_eq(&("betty", Path::<4, 4, 4>::new())));
43    /// ```
44    fn wdm_key_eq<OtherKey>(&self, other: &OtherKey) -> bool
45    where
46        OtherKey: Keylike<MCL, MCC, MPL, S>,
47        S: PartialEq,
48    {
49        self.wdm_subspace_id() == other.wdm_subspace_id() && self.wdm_path() == other.wdm_path()
50    }
51
52    /// 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.
53    ///
54    /// # Examples
55    ///
56    /// ```
57    /// use willow_data_model::prelude::*;
58    ///
59    /// assert!(!("alfie", Path::<4, 4, 4>::new()).wdm_key_ne(&("alfie", Path::<4, 4, 4>::new())));
60    /// assert!(("alfie", Path::<4, 4, 4>::new()).wdm_key_ne(&("betty", Path::<4, 4, 4>::new())));
61    /// ```
62    fn wdm_key_ne<OtherKey>(&self, other: &OtherKey) -> bool
63    where
64        OtherKey: Keylike<MCL, MCC, MPL, S>,
65        S: PartialEq,
66    {
67        self.wdm_subspace_id() != other.wdm_subspace_id() || self.wdm_path() != other.wdm_path()
68    }
69}
70
71impl<const MCL: usize, const MCC: usize, const MPL: usize, S, T> KeylikeExt<MCL, MCC, MPL, S> for T where
72    T: Keylike<MCL, MCC, MPL, S>
73{
74}