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)).
4pub trait Coordinatelike<const MCL: usize, const MCC: usize, const MPL: usize, S>:
5 Keylike<MCL, MCC, MPL, S>
6{
7 /// Returns the [timestamp](https://willowprotocol.org/specs/data-model/index.html#entry_timestamp) of `self`.
8 fn wdm_timestamp(&self) -> Timestamp;
9}
10
11impl<const MCL: usize, const MCC: usize, const MPL: usize, S> Keylike<MCL, MCC, MPL, S>
12 for (S, Path<MCL, MCC, MPL>, Timestamp)
13{
14 fn wdm_subspace_id(&self) -> &S {
15 &self.0
16 }
17
18 fn wdm_path(&self) -> &Path<MCL, MCC, MPL> {
19 &self.1
20 }
21}
22
23impl<const MCL: usize, const MCC: usize, const MPL: usize, S> Coordinatelike<MCL, MCC, MPL, S>
24 for (S, Path<MCL, MCC, MPL>, Timestamp)
25{
26 fn wdm_timestamp(&self) -> Timestamp {
27 self.2
28 }
29}
30
31/// Methods for working with [`Coordinatelikes`](Coordinatelike).
32///
33/// This trait is automatically implemented by all types implementing [`Coordinatelike`].
34pub trait CoordinatelikeExt<const MCL: usize, const MCC: usize, const MPL: usize, S>:
35 Coordinatelike<MCL, MCC, MPL, S> + KeylikeExt<MCL, MCC, MPL, S>
36{
37 /// 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.
38 ///
39 /// # Examples
40 ///
41 /// ```
42 /// use willow_data_model::prelude::*;
43 ///
44 /// # #[cfg(feature = "dev")] {///
45 /// assert!(
46 /// (Alfie, Path::<4, 4, 4>::new(), 25.into())
47 /// .wdm_coordinate_eq(&(Alfie, Path::<4, 4, 4>::new(), 25.into()))
48 /// );
49 /// assert!(
50 /// !(Alfie, Path::<4, 4, 4>::new(), 25.into())
51 /// .wdm_coordinate_eq(&(Betty, Path::<4, 4, 4>::new(), 25.into()))
52 /// );
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 /// # #[cfg(feature = "dev")] {
71 /// assert!(
72 /// !(Alfie, Path::<4, 4, 4>::new(), 25.into())
73 /// .wdm_coordinate_ne(&(Alfie, Path::<4, 4, 4>::new(), 25.into()))
74 /// );
75 /// assert!(
76 /// (Alfie, Path::<4, 4, 4>::new(), 25.into())
77 /// .wdm_coordinate_ne(&(Betty, Path::<4, 4, 4>::new(), 25.into()))
78 /// );
79 /// # }
80 /// ```
81 fn wdm_coordinate_ne<OtherCoordinate>(&self, other: &OtherCoordinate) -> bool
82 where
83 OtherCoordinate: Coordinatelike<MCL, MCC, MPL, S>,
84 S: PartialEq,
85 {
86 self.wdm_key_ne(other) || self.wdm_timestamp() != other.wdm_timestamp()
87 }
88
89 /// Returns whether `self` is included in the given [`Grouping`].
90 ///
91 /// ```
92 /// use willow_data_model::prelude::*;
93 ///
94 /// # #[cfg(feature = "dev")] {
95 /// assert!(
96 /// (Alfie, Path::<4, 4, 4>::new(), 8.into())
97 /// .wdm_is_in(
98 /// &Range3d::<4, 4, 4, TestSubspace>::new(
99 /// SubspaceRange::new_open(Alfie),
100 /// PathRange::full(),
101 /// TimeRange::new_closed(0.into(), 17.into()),
102 /// )
103 /// )
104 /// );
105 /// assert!(
106 /// !(Alfie, Path::<4, 4, 4>::new(), 52.into())
107 /// .wdm_is_in(
108 /// &Range3d::<4, 4, 4, TestSubspace>::new(
109 /// SubspaceRange::new_open(Alfie),
110 /// PathRange::full(),
111 /// TimeRange::new_closed(0.into(), 17.into()),
112 /// )
113 /// )
114 /// );
115 /// # }
116 /// ```
117 fn wdm_is_in<G>(&self, grouping: &G) -> bool
118 where
119 G: Grouping<MCL, MCC, MPL, S>,
120 {
121 grouping.wdm_includes(self)
122 }
123
124 /// Returns whether `self` is included in the intersection of the two given [`Groupings`](Grouping).
125 ///
126 /// ```
127 /// use willow_data_model::prelude::*;
128 ///
129 /// # #[cfg(feature = "dev")] {
130 /// assert!(
131 /// (Alfie, Path::<4, 4, 4>::new(), 25.into())
132 /// .wdm_is_in_intersection(
133 /// &Range3d::<4, 4, 4, TestSubspace>::new(
134 /// SubspaceRange::new_open(Alfie),
135 /// PathRange::full(),
136 /// TimeRange::new_open(17.into()),
137 /// ),
138 /// &Range3d::<4, 4, 4, TestSubspace>::new(
139 /// SubspaceRange::new_open(Alfie),
140 /// PathRange::full(),
141 /// TimeRange::new_closed(0.into(), 28.into()),
142 /// ),
143 /// )
144 /// );
145 /// # }
146 /// ```
147 fn wdm_is_in_intersection<G>(&self, grouping1: &G, grouping2: &G) -> bool
148 where
149 G: Grouping<MCL, MCC, MPL, S>,
150 {
151 grouping1.wdm_includes_in_intersection(grouping2, self)
152 }
153}
154
155impl<const MCL: usize, const MCC: usize, const MPL: usize, S, T> CoordinatelikeExt<MCL, MCC, MPL, S>
156 for T
157where
158 T: Coordinatelike<MCL, MCC, MPL, S> + ?Sized,
159{
160}