thedes_geometry/collections/
set.rs

1use 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}