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    /// # #[cfg(feature = "dev")] {///
47    /// assert!(
48    ///     (Alfie, Path::<4, 4, 4>::new(), 25.into())
49    ///     .wdm_coordinate_eq(&(Alfie, Path::<4, 4, 4>::new(), 25.into()))
50    /// );
51    /// assert!(
52    ///     !(Alfie, Path::<4, 4, 4>::new(), 25.into())
53    ///     .wdm_coordinate_eq(&(Betty, Path::<4, 4, 4>::new(), 25.into()))
54    /// );
55    /// # }
56    /// ```
57    fn wdm_coordinate_eq<OtherCoordinate>(&self, other: &OtherCoordinate) -> bool
58    where
59        OtherCoordinate: Coordinatelike<MCL, MCC, MPL, S>,
60        S: PartialEq,
61    {
62        self.wdm_key_eq(other) && self.wdm_timestamp() == other.wdm_timestamp()
63    }
64
65    /// 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.
66    ///
67    /// # Examples
68    ///
69    /// ```
70    /// use willow_data_model::prelude::*;
71    ///
72    /// # #[cfg(feature = "dev")] {
73    /// assert!(
74    ///     !(Alfie, Path::<4, 4, 4>::new(), 25.into())
75    ///     .wdm_coordinate_ne(&(Alfie, Path::<4, 4, 4>::new(), 25.into()))
76    /// );
77    /// assert!(
78    ///     (Alfie, Path::<4, 4, 4>::new(), 25.into())
79    ///     .wdm_coordinate_ne(&(Betty, Path::<4, 4, 4>::new(), 25.into()))
80    /// );
81    /// # }
82    /// ```
83    fn wdm_coordinate_ne<OtherCoordinate>(&self, other: &OtherCoordinate) -> bool
84    where
85        OtherCoordinate: Coordinatelike<MCL, MCC, MPL, S>,
86        S: PartialEq,
87    {
88        self.wdm_key_ne(other) || self.wdm_timestamp() != other.wdm_timestamp()
89    }
90
91    /// Returns whether `self` is included in the given [`Grouping`].
92    ///
93    /// ```
94    /// use willow_data_model::prelude::*;
95    ///
96    /// # #[cfg(feature = "dev")] {
97    /// assert!(
98    ///     (Alfie, Path::<4, 4, 4>::new(), 8.into())
99    ///     .wdm_is_in(
100    ///         &Range3d::<4, 4, 4, TestSubspace>::new(
101    ///             SubspaceRange::new_open(Alfie),
102    ///             PathRange::full(),
103    ///             TimeRange::new_closed(0.into(), 17.into()),
104    ///         )
105    ///     )
106    /// );
107    /// assert!(
108    ///     !(Alfie, Path::<4, 4, 4>::new(), 52.into())
109    ///     .wdm_is_in(
110    ///         &Range3d::<4, 4, 4, TestSubspace>::new(
111    ///             SubspaceRange::new_open(Alfie),
112    ///             PathRange::full(),
113    ///             TimeRange::new_closed(0.into(), 17.into()),
114    ///         )
115    ///     )
116    /// );
117    /// # }
118    /// ```
119    fn wdm_is_in<G>(&self, grouping: &G) -> bool
120    where
121        G: Grouping<MCL, MCC, MPL, S>,
122    {
123        grouping.wdm_includes(self)
124    }
125
126    /// Returns whether `self` is included in the intersection of the two given [`Groupings`](Grouping).
127    ///
128    /// ```
129    /// use willow_data_model::prelude::*;
130    ///
131    /// # #[cfg(feature = "dev")] {
132    /// assert!(
133    ///     (Alfie, Path::<4, 4, 4>::new(), 25.into())
134    ///     .wdm_is_in_intersection(
135    ///         &Range3d::<4, 4, 4, TestSubspace>::new(
136    ///             SubspaceRange::new_open(Alfie),
137    ///             PathRange::full(),
138    ///             TimeRange::new_open(17.into()),
139    ///         ),
140    ///         &Range3d::<4, 4, 4, TestSubspace>::new(
141    ///             SubspaceRange::new_open(Alfie),
142    ///             PathRange::full(),
143    ///             TimeRange::new_closed(0.into(), 28.into()),
144    ///         ),
145    ///     )
146    /// );
147    /// # }
148    /// ```
149    fn wdm_is_in_intersection<G>(&self, grouping1: &G, grouping2: &G) -> bool
150    where
151        G: Grouping<MCL, MCC, MPL, S>,
152    {
153        grouping1.wdm_includes_in_intersection(grouping2, self)
154    }
155}
156
157impl<const MCL: usize, const MCC: usize, const MPL: usize, S, T> CoordinatelikeExt<MCL, MCC, MPL, S>
158    for T
159where
160    T: Coordinatelike<MCL, MCC, MPL, S>,
161{
162}