thedes_geometry/collections/
set.rs1use std::{borrow::Borrow, fmt, marker::PhantomData};
2
3use serde::{
4 Deserialize,
5 Deserializer,
6 Serialize,
7 Serializer,
8 de::{SeqAccess, Visitor},
9 ser::SerializeSeq,
10};
11
12use crate::{CoordPair, coords::CoordPairBounds, orientation::Axis};
13
14use super::map::{self, CoordMap};
15
16#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
17pub struct CoordSet<C> {
18 inner: CoordMap<C, ()>,
19}
20
21impl<C> Default for CoordSet<C> {
22 fn default() -> Self {
23 Self::new()
24 }
25}
26
27impl<C> CoordSet<C> {
28 pub fn new() -> Self {
29 Self { inner: CoordMap::new() }
30 }
31
32 pub fn len(&self) -> usize {
33 self.inner.len()
34 }
35
36 pub fn is_empty(&self) -> bool {
37 self.inner.is_empty()
38 }
39}
40
41impl<C> CoordSet<C>
42where
43 C: Ord,
44{
45 pub fn contains<C0>(&self, elem: CoordPair<&C0>) -> bool
46 where
47 C: Borrow<C0>,
48 C0: Ord,
49 {
50 self.get(elem).is_some()
51 }
52
53 pub fn get<C0>(&self, elem: CoordPair<&C0>) -> Option<CoordPair<&C>>
54 where
55 C: Borrow<C0>,
56 C0: Ord,
57 {
58 let (stored, _) = self.inner.get_key_value(elem)?;
59 Some(stored)
60 }
61}
62
63impl<C> CoordSet<C>
64where
65 C: Ord + Clone,
66{
67 pub fn insert(&mut self, elem: CoordPair<C>) -> bool {
68 self.inner.insert(elem, ()).is_none()
69 }
70}
71
72impl<C> CoordSet<C>
73where
74 C: Ord,
75{
76 pub fn remove<C0>(&mut self, elem: CoordPair<&C0>) -> bool
77 where
78 C: Borrow<C0>,
79 C0: Ord,
80 {
81 self.inner.remove(elem).is_some()
82 }
83
84 pub fn range<'q, 'a, R, C0>(
85 &'a self,
86 higher_axis: Axis,
87 ranges: R,
88 ) -> Range<'q, 'a, C0, C>
89 where
90 R: Into<CoordPairBounds<&'q C0>>,
91 C: Borrow<C0>,
92 C0: Ord + 'q,
93 {
94 Range { inner: self.inner.range(higher_axis, ranges) }
95 }
96
97 pub fn next_neighbor<C0>(
98 &self,
99 axis: Axis,
100 key: CoordPair<&C0>,
101 ) -> Option<CoordPair<&C>>
102 where
103 C: Borrow<C0>,
104 C0: Ord,
105 {
106 let (elem, _) = self.inner.next_neighbor(axis, key)?;
107 Some(elem)
108 }
109
110 pub fn prev_neighbor<C0>(
111 &self,
112 axis: Axis,
113 key: CoordPair<&C0>,
114 ) -> Option<CoordPair<&C>>
115 where
116 C: Borrow<C0>,
117 C0: Ord,
118 {
119 let (elem, _) = self.inner.prev_neighbor(axis, key)?;
120 Some(elem)
121 }
122
123 pub fn last_neighbor<C0>(
124 &self,
125 axis: Axis,
126 key: CoordPair<&C0>,
127 ) -> Option<CoordPair<&C>>
128 where
129 C: Borrow<C0>,
130 C0: Ord,
131 {
132 let (elem, _) = self.inner.last_neighbor(axis, key)?;
133 Some(elem)
134 }
135
136 pub fn first_neighbor<C0>(
137 &self,
138 axis: Axis,
139 key: CoordPair<&C0>,
140 ) -> Option<CoordPair<&C>>
141 where
142 C: Borrow<C0>,
143 C0: Ord,
144 {
145 let (elem, _) = self.inner.first_neighbor(axis, key)?;
146 Some(elem)
147 }
148}
149
150impl<C> CoordSet<C> {
151 pub fn iter(&self, higher_axis: Axis) -> Iter<C> {
152 Iter { inner: self.inner.keys(higher_axis) }
153 }
154
155 pub fn rows(&self) -> Iter<C> {
156 self.iter(Axis::Y)
157 }
158
159 pub fn columns(&self) -> Iter<C> {
160 self.iter(Axis::X)
161 }
162}
163
164impl<C> CoordSet<C>
165where
166 C: Clone,
167{
168 pub fn into_iter_with(self, higher_axis: Axis) -> IntoIter<C> {
169 IntoIter { inner: self.inner.into_keys(higher_axis) }
170 }
171
172 pub fn into_rows(self) -> IntoIter<C> {
173 self.into_iter_with(Axis::Y)
174 }
175
176 pub fn into_columns(self) -> IntoIter<C> {
177 self.into_iter_with(Axis::X)
178 }
179}
180
181impl<C> Serialize for CoordSet<C>
182where
183 C: Serialize,
184{
185 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
186 where
187 S: Serializer,
188 {
189 let mut set_serializer = serializer.serialize_seq(Some(self.len()))?;
190 for elem in self.rows() {
191 set_serializer.serialize_element(&elem)?;
192 }
193 set_serializer.end()
194 }
195}
196
197impl<'de, C> Deserialize<'de> for CoordSet<C>
198where
199 C: Deserialize<'de> + Ord + Clone,
200{
201 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
202 where
203 D: Deserializer<'de>,
204 {
205 struct CoordSetVisitor<C0> {
206 _marker: PhantomData<CoordPair<C0>>,
207 }
208
209 impl<'de0, C0> Visitor<'de0> for CoordSetVisitor<C0>
210 where
211 C0: Deserialize<'de0> + Ord + Clone,
212 {
213 type Value = CoordSet<C0>;
214
215 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
216 write!(formatter, "a coordinate set")
217 }
218
219 fn visit_seq<A>(
220 self,
221 mut access: A,
222 ) -> Result<Self::Value, A::Error>
223 where
224 A: SeqAccess<'de0>,
225 {
226 let mut set = CoordSet::new();
227 while let Some(elem) = access.next_element()? {
228 set.insert(elem);
229 }
230 Ok(set)
231 }
232 }
233
234 deserializer.deserialize_seq(CoordSetVisitor { _marker: PhantomData })
235 }
236}
237
238impl<'a, C> IntoIterator for &'a CoordSet<C> {
239 type Item = CoordPair<&'a C>;
240 type IntoIter = Iter<'a, C>;
241
242 fn into_iter(self) -> Self::IntoIter {
243 self.rows()
244 }
245}
246
247impl<C> IntoIterator for CoordSet<C>
248where
249 C: Clone,
250{
251 type Item = CoordPair<C>;
252 type IntoIter = IntoIter<C>;
253
254 fn into_iter(self) -> Self::IntoIter {
255 self.into_rows()
256 }
257}
258
259#[derive(Debug, Clone)]
260pub struct Range<'q, 'a, C0, C> {
261 inner: map::Range<'q, 'a, C0, C, ()>,
262}
263
264impl<'q, 'a, C0, C> Iterator for Range<'q, 'a, C0, C>
265where
266 C: Ord + Borrow<C0>,
267 C0: Ord,
268{
269 type Item = CoordPair<&'a C>;
270
271 fn next(&mut self) -> Option<Self::Item> {
272 self.inner.next().map(|(elem, _)| elem)
273 }
274
275 fn size_hint(&self) -> (usize, Option<usize>) {
276 self.inner.size_hint()
277 }
278}
279
280impl<'q, 'a, C0, C> DoubleEndedIterator for Range<'q, 'a, C0, C>
281where
282 C: Ord + Borrow<C0>,
283 C0: Ord,
284{
285 fn next_back(&mut self) -> Option<Self::Item> {
286 self.inner.next_back().map(|(elem, _)| elem)
287 }
288}
289
290#[derive(Debug, Clone)]
291pub struct Iter<'a, C> {
292 inner: map::Keys<'a, C, ()>,
293}
294
295impl<'a, C> Iterator for Iter<'a, C> {
296 type Item = CoordPair<&'a C>;
297
298 fn next(&mut self) -> Option<Self::Item> {
299 self.inner.next()
300 }
301
302 fn size_hint(&self) -> (usize, Option<usize>) {
303 self.inner.size_hint()
304 }
305}
306
307impl<'a, C> DoubleEndedIterator for Iter<'a, C> {
308 fn next_back(&mut self) -> Option<Self::Item> {
309 self.inner.next_back()
310 }
311}
312
313#[derive(Debug)]
314pub struct IntoIter<C> {
315 inner: map::IntoKeys<C, ()>,
316}
317
318impl<C> Iterator for IntoIter<C>
319where
320 C: Clone,
321{
322 type Item = CoordPair<C>;
323
324 fn next(&mut self) -> Option<Self::Item> {
325 self.inner.next()
326 }
327
328 fn size_hint(&self) -> (usize, Option<usize>) {
329 self.inner.size_hint()
330 }
331}
332
333impl<C> DoubleEndedIterator for IntoIter<C>
334where
335 C: Clone,
336{
337 fn next_back(&mut self) -> Option<Self::Item> {
338 self.inner.next_back()
339 }
340}