willow_data_model/groupings/
coordinatelike.rs

1use crate::prelude::*;
2
3/// A coordinatelike value represents a point in the [three-dimensional willow space](https://willowprotocol.org/specs/grouping-entries/index.html#D3Range) (within a given [namespace](https://willowprotocol.org/specs/data-model/index.html#namespace)).
4///
5/// This trait does not include the namespace id, because our implementation separates entry storage by namespace from the get-go.
6pub trait Coordinatelike<const MCL: usize, const MCC: usize, const MPL: usize, S>:
7    Keylike<MCL, MCC, MPL, S>
8{
9    /// Returns the [timestamp](https://willowprotocol.org/specs/data-model/index.html#entry_timestamp) of `self`.
10    fn wdm_timestamp(&self) -> Timestamp;
11}
12
13impl<const MCL: usize, const MCC: usize, const MPL: usize, S> Keylike<MCL, MCC, MPL, S>
14    for (S, Path<MCL, MCC, MPL>, Timestamp)
15{
16    fn wdm_subspace_id(&self) -> &S {
17        &self.0
18    }
19
20    fn wdm_path(&self) -> &Path<MCL, MCC, MPL> {
21        &self.1
22    }
23}
24
25impl<const MCL: usize, const MCC: usize, const MPL: usize, S> Coordinatelike<MCL, MCC, MPL, S>
26    for (S, Path<MCL, MCC, MPL>, Timestamp)
27{
28    fn wdm_timestamp(&self) -> Timestamp {
29        self.2
30    }
31}
32
33/// Methods for working with [`Coordinatelikes`](Coordinatelike).
34///
35/// This trait is automatically implemented by all types implementing [`Coordinatelike`].
36pub trait CoordinatelikeExt<const MCL: usize, const MCC: usize, const MPL: usize, S>:
37    Coordinatelike<MCL, MCC, MPL, S> + KeylikeExt<MCL, MCC, MPL, S>
38{
39    /// Returns whether `self` and `other` describe equal coordinates, i.e., whether their [subspace ids](Keylike::wdm_subspace_id), [paths](Keylike::wdm_path), and [timestamps](Coordinatelike::wdm_timestamp) are all equal.
40    ///
41    /// # Examples
42    ///
43    /// ```
44    /// use willow_data_model::prelude::*;
45    ///
46    /// assert!(
47    ///     ([7; 32], Path::<4, 4, 4>::new(), 25.into())
48    ///     .wdm_coordinate_eq(&([7; 32], Path::<4, 4, 4>::new(), 25.into()))
49    /// );
50    /// assert!(
51    ///     !([7; 32], Path::<4, 4, 4>::new(), 25.into())
52    ///     .wdm_coordinate_eq(&([8; 32], Path::<4, 4, 4>::new(), 25.into()))
53    /// );
54    /// ```
55    fn wdm_coordinate_eq<OtherCoordinate>(&self, other: &OtherCoordinate) -> bool
56    where
57        OtherCoordinate: Coordinatelike<MCL, MCC, MPL, S>,
58        S: PartialEq,
59    {
60        self.wdm_key_eq(other) && self.wdm_timestamp() == other.wdm_timestamp()
61    }
62
63    /// Returns whether `self` and `other` describe non-equal coordinates, i.e., whether their [subspace ids](Keylike::wdm_subspace_id), [paths](Keylike::wdm_path), and [timestamps](Coordinatelike::wdm_timestamp) are not all equal.
64    ///
65    /// # Examples
66    ///
67    /// ```
68    /// use willow_data_model::prelude::*;
69    ///
70    /// assert!(
71    ///     !([7; 32], Path::<4, 4, 4>::new(), 25.into())
72    ///     .wdm_coordinate_ne(&([7; 32], Path::<4, 4, 4>::new(), 25.into()))
73    /// );
74    /// assert!(
75    ///     ([7; 32], Path::<4, 4, 4>::new(), 25.into())
76    ///     .wdm_coordinate_ne(&([8; 32], Path::<4, 4, 4>::new(), 25.into()))
77    /// );
78    /// ```
79    fn wdm_coordinate_ne<OtherCoordinate>(&self, other: &OtherCoordinate) -> bool
80    where
81        OtherCoordinate: Coordinatelike<MCL, MCC, MPL, S>,
82        S: PartialEq,
83    {
84        self.wdm_key_ne(other) || self.wdm_timestamp() != other.wdm_timestamp()
85    }
86
87    /// Returns whether `self` is included in the given [`Grouping`].
88    ///
89    /// ```
90    /// use willow_data_model::prelude::*;
91    ///
92    /// assert!(
93    ///     ([7; 32], Path::<4, 4, 4>::new(), 8.into())
94    ///     .wdm_is_in(
95    ///         &Range3d::<4, 4, 4, [u8; 32]>::new([7; 32].., .., ..Timestamp::from(17))
96    ///     )
97    /// );
98    /// assert!(
99    ///     !([7; 32], Path::<4, 4, 4>::new(), 52.into())
100    ///     .wdm_is_in(
101    ///         &Range3d::<4, 4, 4, [u8; 32]>::new([7; 32].., .., ..Timestamp::from(17))
102    ///     )
103    /// );
104    /// ```
105    fn wdm_is_in<G>(&self, grouping: &G) -> bool
106    where
107        G: Grouping<MCL, MCC, MPL, S>,
108    {
109        grouping.wdm_includes(self)
110    }
111
112    /// Returns whether `self` is included in the intersection of the two given [`Groupings`](Grouping).
113    ///
114    /// ```
115    /// use willow_data_model::prelude::*;
116    ///
117    /// assert!(
118    ///     ([7; 32], Path::<4, 4, 4>::new(), 25.into())
119    ///     .wdm_is_in_intersection(
120    ///         &Range3d::<4, 4, 4, [u8; 32]>::new([7; 32].., .., Timestamp::from(17)..),
121    ///         &Range3d::<4, 4, 4, [u8; 32]>::new([7; 32].., .., ..Timestamp::from(28)),
122    ///     )
123    /// );
124    /// assert!(
125    ///     !([7; 32], Path::<4, 4, 4>::new(), 30.into())
126    ///     .wdm_is_in_intersection(
127    ///         &Range3d::<4, 4, 4, [u8; 32]>::new([7; 32].., .., Timestamp::from(17)..),
128    ///         &Range3d::<4, 4, 4, [u8; 32]>::new([7; 32].., .., ..Timestamp::from(28)),
129    ///     )
130    /// );
131    /// assert!(
132    ///     !([7; 32], Path::<4, 4, 4>::new(), 14.into())
133    ///     .wdm_is_in_intersection(
134    ///         &Range3d::<4, 4, 4, [u8; 32]>::new([7; 32].., .., Timestamp::from(17)..),
135    ///         &Range3d::<4, 4, 4, [u8; 32]>::new([7; 32].., .., ..Timestamp::from(28)),
136    ///     )
137    /// );
138    /// ```
139    fn wdm_is_in_intersection<G>(&self, grouping1: &G, grouping2: &G) -> bool
140    where
141        G: Grouping<MCL, MCC, MPL, S>,
142    {
143        grouping1.wdm_includes_in_intersection(grouping2, self)
144    }
145}
146
147impl<const MCL: usize, const MCC: usize, const MPL: usize, S, T> CoordinatelikeExt<MCL, MCC, MPL, S>
148    for T
149where
150    T: Coordinatelike<MCL, MCC, MPL, S>,
151{
152}