segment_map/
segment.rs

1use crate::{
2    Bounded,
3    Next,
4};
5
6#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
7pub struct Segment<K> {
8    lower: K,
9    upper: K,
10}
11
12impl<K> Segment<K> 
13where
14    K: PartialOrd
15{
16    pub fn new(lower: K, upper: K) -> Segment<K> {
17        Segment { lower, upper }
18    }
19
20    pub fn closed_open(lower: K, upper: K) -> Segment<K> {
21        Segment { lower, upper }
22    }
23
24    pub fn contains(&self, value: &K) -> bool {
25        (&self.lower <= value) && (value < &self.upper)
26    }
27
28    pub fn encloses(&self, other: &Segment<K>) -> bool {
29        (self.lower <= other.lower) && (other.upper <= self.upper)
30    }
31
32    pub fn is_connected(&self, other: &Segment<K>) -> bool {
33        (self.lower <= other.upper) && (other.lower <= self.upper)
34    }
35
36    pub fn is_empty(&self) -> bool {
37        self.lower == self.upper
38    }
39
40    pub fn lower(&self) -> &K {
41        &self.lower
42    }
43
44    pub fn upper(&self) -> &K {
45        &self.upper
46    }
47}
48
49impl<K> Segment<K> 
50where
51    K: Clone + PartialOrd
52{
53    pub fn intersection(&self, other: &Segment<K>) -> Option<Segment<K>> {
54        if self.is_connected(other) {
55            Some(Segment {
56                lower: if self.lower < other.lower { other.lower.clone() } else { self.lower.clone() },
57                upper: if other.upper < self.upper { other.upper.clone() } else { self.upper.clone() },
58            })
59        } else { None }
60    }
61
62    pub fn span(&self, other: &Segment<K>) -> Segment<K> {
63        Segment {
64            lower: if self.lower < other.lower { self.lower.clone() } else { other.lower.clone() },
65            upper: if other.upper < self.upper { self.upper.clone() } else { other.upper.clone() },
66        }
67    }
68}
69
70impl<K> Segment<K>
71where
72    K: PartialOrd + Default
73{
74    pub fn empty() -> Segment<K> {
75        Segment { lower: K::default(), upper: K::default() }
76    }
77}
78
79impl<K> Segment<K> 
80where
81    K: PartialOrd + Next
82{
83    pub fn singleton(value: K) -> Segment<K> {
84        Segment { lower: value.clone(), upper: value.next_unchecked() }
85    }
86
87    pub fn open(lower: K, upper: K) -> Segment<K> {
88        Segment { lower: lower.next_unchecked(), upper }
89    }
90
91    pub fn closed(lower: K, upper: K) -> Segment<K> {
92        Segment { lower, upper: upper.next_unchecked() }
93    }
94
95    pub fn open_closed(lower: K, upper: K) -> Segment<K> {
96        Segment { lower: lower.next_unchecked(), upper: upper.next_unchecked() }
97    }
98}
99
100impl<K> Segment<K> 
101where
102    K: Bounded + PartialOrd + Next
103{
104    pub fn at_most(value: K) -> Segment<K> {
105        Segment { lower: K::min(), upper: value.next_unchecked() }
106    }
107
108    pub fn greater_than(value: K) -> Segment<K> {
109        Segment { lower: value.next_unchecked(), upper: K::max() }
110    }
111}
112
113impl<K> Segment<K>
114where
115    K: Bounded + PartialOrd
116{
117    pub fn at_least(value: K) -> Segment<K> {
118        Segment { lower: value, upper: K::max() }
119    }
120
121    pub fn less_than(value: K) -> Segment<K> {
122        Segment { lower: K::min(), upper: value }
123    }
124
125    pub fn all() -> Segment<K> {
126        Segment { lower: K::min(), upper: K::max() }
127    }
128}
129
130#[cfg(test)]
131mod tests {
132    use crate::Segment;
133
134    #[test]
135    fn test_contains() {
136        //
137        // -----[-----)----- -> false
138        //   ^
139        assert!(!Segment::new(5, 11).contains(&2));
140
141        //
142        // -----[-----)----- -> true
143        //      ^
144        assert!(Segment::new(5, 11).contains(&5));
145
146        //
147        // -----[-----)----- -> true
148        //         ^
149        assert!(Segment::new(5, 11).contains(&8));
150
151        //
152        // -----[-----)----- -> false
153        //            ^
154        assert!(!Segment::new(5, 11).contains(&11));
155
156        //
157        // -----[-----)----- -> false
158        //               ^
159        assert!(!Segment::new(5, 11).contains(&14));
160    }
161
162    #[test]
163    fn test_encloses() {
164        // -----[-----)-----
165        //                   -> true
166        // -----[-----)-----
167        assert!(Segment::new(5, 11).encloses(&Segment::new(5, 11)));
168
169        // -------[-)-------
170        //                   -> false
171        // -----[-----)-----
172        assert!(!Segment::new(7, 9).encloses(&Segment::new(5, 11)));
173
174        // -----[-----)-----
175        //                   -> true
176        // -------[-)-------
177        assert!(Segment::new(5, 11).encloses(&Segment::new(7, 9)));
178
179        // -----[---)-------
180        //                   -> false
181        // -----[-----)-----
182        assert!(!Segment::new(5, 9).encloses(&Segment::new(5, 11)));
183
184        // -----[-----)-----
185        //                   -> true
186        // -----[---)-------
187        assert!(Segment::new(5, 11).encloses(&Segment::new(5, 9)));
188
189        // -------[---)-----
190        //                   -> false
191        // -----[-----)-----
192        assert!(!Segment::new(7, 11).encloses(&Segment::new(5, 11)));
193
194        // -----[-----)-----
195        //                   -> true
196        // -------[---)----- 
197        assert!(Segment::new(5, 11).encloses(&Segment::new(7, 11)));
198
199        // -----[-----)-----
200        //                   -> false
201        // -------[-----)---
202        assert!(!Segment::new(5, 11).encloses(&Segment::new(7, 13)));
203
204        // -------[-----)---
205        //                   -> false
206        // -----[-----)-----
207        assert!(!Segment::new(7, 13).encloses(&Segment::new(5, 11)));
208
209        // --------[-----)--
210        //                   -> false
211        // --[-----)--------
212        assert!(!Segment::new(8, 14).encloses(&Segment::new(2, 8)));
213
214        // --[-----)--------
215        //                   -> false
216        // --------[-----)--
217        assert!(!Segment::new(2, 8).encloses(&Segment::new(8, 14)));
218
219        // ----------[-----)
220        //                   -> false
221        // [-----)----------
222        assert!(!Segment::new(10, 16).encloses(&Segment::new(0, 6)));
223
224        // [-----)----------
225        //                   -> false
226        // ----------[-----)
227        assert!(!Segment::new(0, 6).encloses(&Segment::new(10, 16)));
228    }
229
230    #[test]
231    fn test_intersection() {
232        // -----[-----)-----
233        //                   -> -----[-----)-----
234        // -----[-----)-----
235        assert_eq!(Some(Segment::new(5, 11)), Segment::new(5, 11).intersection(&Segment::new(5, 11)));
236
237        // -------[-)-------
238        //                   -> -------[-)-------
239        // -----[-----)-----
240        assert_eq!(Some(Segment::new(7, 9)), Segment::new(7, 9).intersection(&Segment::new(5, 11)));
241
242        // -----[-----)-----
243        //                   -> -------[-)-------
244        // -------[-)-------
245        assert_eq!(Some(Segment::new(7, 9)), Segment::new(5, 11).intersection(&Segment::new(7, 9)));
246
247        // -----[---)-------
248        //                   -> -----[---)-------
249        // -----[-----)-----
250        assert_eq!(Some(Segment::new(5, 9)), Segment::new(5, 9).intersection(&Segment::new(5, 11)));
251
252        // -----[-----)-----
253        //                   -> -----[---)-------
254        // -----[---)-------
255        assert_eq!(Some(Segment::new(5, 9)), Segment::new(5, 11).intersection(&Segment::new(5, 9)));
256
257        // -------[---)-----
258        //                   -> -------[---)-----
259        // -----[-----)-----
260        assert_eq!(Some(Segment::new(7, 11)), Segment::new(7, 11).intersection(&Segment::new(5, 11)));
261
262        // -----[-----)-----
263        //                   -> -------[---)-----
264        // -------[---)----- 
265        assert_eq!(Some(Segment::new(7, 11)), Segment::new(5, 11).intersection(&Segment::new(7, 11)));
266
267        // -----[-----)-----
268        //                   -> -------[---)-----
269        // -------[-----)---
270        assert_eq!(Some(Segment::new(7, 11)), Segment::new(5, 11).intersection(&Segment::new(7, 13)));
271
272        // -------[-----)---
273        //                   -> -------[---)-----
274        // -----[-----)-----
275        assert_eq!(Some(Segment::new(7, 11)), Segment::new(7, 13).intersection(&Segment::new(5, 11)));
276
277        // --------[-----)--
278        //                   -> -----------------
279        // --[-----)--------
280        assert_eq!(Some(Segment::new(8, 8)), Segment::new(8, 14).intersection(&Segment::new(2, 8)));
281
282        // --[-----)--------
283        //                   -> -----------------
284        // --------[-----)--
285        assert_eq!(Some(Segment::new(8, 8)), Segment::new(2, 8).intersection(&Segment::new(8, 14)));
286
287        // ----------[-----)
288        //                   -> None
289        // [-----)----------
290        assert_eq!(None, Segment::new(10, 16).intersection(&Segment::new(0, 6)));
291
292        // [-----)----------
293        //                   -> None
294        // ----------[-----)
295        assert_eq!(None, Segment::new(0, 6).intersection(&Segment::new(10, 16)));
296    }
297
298    #[test]
299    fn test_is_connected() {
300        // -----[-----)-----
301        //                   -> true
302        // -----[-----)-----
303        assert!(Segment::new(5, 11).is_connected(&Segment::new(5, 11)));
304
305        // -------[-)-------
306        //                   -> true
307        // -----[-----)-----
308        assert!(Segment::new(7, 9).is_connected(&Segment::new(5, 11)));
309
310        // -----[-----)-----
311        //                   -> true
312        // -------[-)-------
313        assert!(Segment::new(5, 11).is_connected(&Segment::new(7, 9)));
314
315        // -----[---)-------
316        //                   -> true
317        // -----[-----)-----
318        assert!(Segment::new(5, 9).is_connected(&Segment::new(5, 11)));
319
320        // -----[-----)-----
321        //                   -> true
322        // -----[---)-------
323        assert!(Segment::new(5, 11).is_connected(&Segment::new(5, 9)));
324
325        // -------[---)-----
326        //                   -> true
327        // -----[-----)-----
328        assert!(Segment::new(7, 11).is_connected(&Segment::new(5, 11)));
329
330        // -----[-----)-----
331        //                   -> true
332        // -------[---)----- 
333        assert!(Segment::new(5, 11).is_connected(&Segment::new(7, 11)));
334
335        // -----[-----)-----
336        //                   -> true
337        // -------[-----)---
338        assert!(Segment::new(5, 11).is_connected(&Segment::new(7, 13)));
339
340        // -------[-----)---
341        //                   -> true
342        // -----[-----)-----
343        assert!(Segment::new(7, 13).is_connected(&Segment::new(5, 11)));
344
345        // --------[-----)--
346        //                   -> true
347        // --[-----)--------
348        assert!(Segment::new(8, 14).is_connected(&Segment::new(2, 8)));
349
350        // --[-----)--------
351        //                   -> true
352        // --------[-----)--
353        assert!(Segment::new(2, 8).is_connected(&Segment::new(8, 14)));
354
355        // ----------[-----)
356        //                   -> false
357        // [-----)----------
358        assert!(!Segment::new(10, 16).is_connected(&Segment::new(0, 6)));
359
360        // [-----)----------
361        //                   -> false
362        // ----------[-----)
363        assert!(!Segment::new(0, 6).is_connected(&Segment::new(10, 16)));
364    }
365    
366    #[test]
367    fn test_span() {
368        // -----[-----)-----
369        //                   -> -----[-----)-----
370        // -----[-----)-----
371        assert_eq!(Segment::new(5, 11), Segment::new(5, 11).span(&Segment::new(5, 11)));
372
373        // -------[-)-------
374        //                   -> -----[-----)-----
375        // -----[-----)-----
376        assert_eq!(Segment::new(5, 11), Segment::new(7, 9).span(&Segment::new(5, 11)));
377
378        // -----[-----)-----
379        //                   -> -----[-----)-----
380        // -------[-)-------
381        assert_eq!(Segment::new(5, 11), Segment::new(5, 11).span(&Segment::new(7, 9)));
382
383        // -----[---)-------
384        //                   -> -----[-----)-----
385        // -----[-----)-----
386        assert_eq!(Segment::new(5, 11), Segment::new(5, 9).span(&Segment::new(5, 11)));
387
388        // -----[-----)-----
389        //                   -> -----[-----)-----
390        // -----[---)-------
391        assert_eq!(Segment::new(5, 11), Segment::new(5, 11).span(&Segment::new(5, 9)));
392
393        // -------[---)-----
394        //                   -> -----[-----)-----
395        // -----[-----)-----
396        assert_eq!(Segment::new(5, 11), Segment::new(7, 11).span(&Segment::new(5, 11)));
397
398        // -----[-----)-----
399        //                   -> -----[-----)-----
400        // -------[---)----- 
401        assert_eq!(Segment::new(5, 11), Segment::new(5, 11).span(&Segment::new(7, 11)));
402
403        // -----[-----)-----
404        //                   -> -----[-------)---
405        // -------[-----)---
406        assert_eq!(Segment::new(5, 13), Segment::new(5, 11).span(&Segment::new(7, 13)));
407
408        // -------[-----)---
409        //                   -> -----[-------)---
410        // -----[-----)-----
411        assert_eq!(Segment::new(5, 13), Segment::new(7, 13).span(&Segment::new(5, 11)));
412
413        // --------[-----)--
414        //                   -> --[-----------)--
415        // --[-----)--------
416        assert_eq!(Segment::new(2, 14), Segment::new(8, 14).span(&Segment::new(2, 8)));
417
418        // --[-----)--------
419        //                   -> --[-----------)--
420        // --------[-----)--
421        assert_eq!(Segment::new(2, 14), Segment::new(2, 8).span(&Segment::new(8, 14)));
422
423        // ----------[-----)
424        //                   -> [---------------)
425        // [-----)----------
426        assert_eq!(Segment::new(0, 16), Segment::new(10, 16).span(&Segment::new(0, 6)));
427
428        // [-----)----------
429        //                   -> [---------------)
430        // ----------[-----)
431        assert_eq!(Segment::new(0, 16), Segment::new(0, 6).span(&Segment::new(10, 16)));
432    }
433}