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}