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 assert!(!Segment::new(5, 11).contains(&2));
140
141 assert!(Segment::new(5, 11).contains(&5));
145
146 assert!(Segment::new(5, 11).contains(&8));
150
151 assert!(!Segment::new(5, 11).contains(&11));
155
156 assert!(!Segment::new(5, 11).contains(&14));
160 }
161
162 #[test]
163 fn test_encloses() {
164 assert!(Segment::new(5, 11).encloses(&Segment::new(5, 11)));
168
169 assert!(!Segment::new(7, 9).encloses(&Segment::new(5, 11)));
173
174 assert!(Segment::new(5, 11).encloses(&Segment::new(7, 9)));
178
179 assert!(!Segment::new(5, 9).encloses(&Segment::new(5, 11)));
183
184 assert!(Segment::new(5, 11).encloses(&Segment::new(5, 9)));
188
189 assert!(!Segment::new(7, 11).encloses(&Segment::new(5, 11)));
193
194 assert!(Segment::new(5, 11).encloses(&Segment::new(7, 11)));
198
199 assert!(!Segment::new(5, 11).encloses(&Segment::new(7, 13)));
203
204 assert!(!Segment::new(7, 13).encloses(&Segment::new(5, 11)));
208
209 assert!(!Segment::new(8, 14).encloses(&Segment::new(2, 8)));
213
214 assert!(!Segment::new(2, 8).encloses(&Segment::new(8, 14)));
218
219 assert!(!Segment::new(10, 16).encloses(&Segment::new(0, 6)));
223
224 assert!(!Segment::new(0, 6).encloses(&Segment::new(10, 16)));
228 }
229
230 #[test]
231 fn test_intersection() {
232 assert_eq!(Some(Segment::new(5, 11)), Segment::new(5, 11).intersection(&Segment::new(5, 11)));
236
237 assert_eq!(Some(Segment::new(7, 9)), Segment::new(7, 9).intersection(&Segment::new(5, 11)));
241
242 assert_eq!(Some(Segment::new(7, 9)), Segment::new(5, 11).intersection(&Segment::new(7, 9)));
246
247 assert_eq!(Some(Segment::new(5, 9)), Segment::new(5, 9).intersection(&Segment::new(5, 11)));
251
252 assert_eq!(Some(Segment::new(5, 9)), Segment::new(5, 11).intersection(&Segment::new(5, 9)));
256
257 assert_eq!(Some(Segment::new(7, 11)), Segment::new(7, 11).intersection(&Segment::new(5, 11)));
261
262 assert_eq!(Some(Segment::new(7, 11)), Segment::new(5, 11).intersection(&Segment::new(7, 11)));
266
267 assert_eq!(Some(Segment::new(7, 11)), Segment::new(5, 11).intersection(&Segment::new(7, 13)));
271
272 assert_eq!(Some(Segment::new(7, 11)), Segment::new(7, 13).intersection(&Segment::new(5, 11)));
276
277 assert_eq!(Some(Segment::new(8, 8)), Segment::new(8, 14).intersection(&Segment::new(2, 8)));
281
282 assert_eq!(Some(Segment::new(8, 8)), Segment::new(2, 8).intersection(&Segment::new(8, 14)));
286
287 assert_eq!(None, Segment::new(10, 16).intersection(&Segment::new(0, 6)));
291
292 assert_eq!(None, Segment::new(0, 6).intersection(&Segment::new(10, 16)));
296 }
297
298 #[test]
299 fn test_is_connected() {
300 assert!(Segment::new(5, 11).is_connected(&Segment::new(5, 11)));
304
305 assert!(Segment::new(7, 9).is_connected(&Segment::new(5, 11)));
309
310 assert!(Segment::new(5, 11).is_connected(&Segment::new(7, 9)));
314
315 assert!(Segment::new(5, 9).is_connected(&Segment::new(5, 11)));
319
320 assert!(Segment::new(5, 11).is_connected(&Segment::new(5, 9)));
324
325 assert!(Segment::new(7, 11).is_connected(&Segment::new(5, 11)));
329
330 assert!(Segment::new(5, 11).is_connected(&Segment::new(7, 11)));
334
335 assert!(Segment::new(5, 11).is_connected(&Segment::new(7, 13)));
339
340 assert!(Segment::new(7, 13).is_connected(&Segment::new(5, 11)));
344
345 assert!(Segment::new(8, 14).is_connected(&Segment::new(2, 8)));
349
350 assert!(Segment::new(2, 8).is_connected(&Segment::new(8, 14)));
354
355 assert!(!Segment::new(10, 16).is_connected(&Segment::new(0, 6)));
359
360 assert!(!Segment::new(0, 6).is_connected(&Segment::new(10, 16)));
364 }
365
366 #[test]
367 fn test_span() {
368 assert_eq!(Segment::new(5, 11), Segment::new(5, 11).span(&Segment::new(5, 11)));
372
373 assert_eq!(Segment::new(5, 11), Segment::new(7, 9).span(&Segment::new(5, 11)));
377
378 assert_eq!(Segment::new(5, 11), Segment::new(5, 11).span(&Segment::new(7, 9)));
382
383 assert_eq!(Segment::new(5, 11), Segment::new(5, 9).span(&Segment::new(5, 11)));
387
388 assert_eq!(Segment::new(5, 11), Segment::new(5, 11).span(&Segment::new(5, 9)));
392
393 assert_eq!(Segment::new(5, 11), Segment::new(7, 11).span(&Segment::new(5, 11)));
397
398 assert_eq!(Segment::new(5, 11), Segment::new(5, 11).span(&Segment::new(7, 11)));
402
403 assert_eq!(Segment::new(5, 13), Segment::new(5, 11).span(&Segment::new(7, 13)));
407
408 assert_eq!(Segment::new(5, 13), Segment::new(7, 13).span(&Segment::new(5, 11)));
412
413 assert_eq!(Segment::new(2, 14), Segment::new(8, 14).span(&Segment::new(2, 8)));
417
418 assert_eq!(Segment::new(2, 14), Segment::new(2, 8).span(&Segment::new(8, 14)));
422
423 assert_eq!(Segment::new(0, 16), Segment::new(10, 16).span(&Segment::new(0, 6)));
427
428 assert_eq!(Segment::new(0, 16), Segment::new(0, 6).span(&Segment::new(10, 16)));
432 }
433}