range_ext/
intersect.rs

1use std::cmp::{Ordering, PartialOrd};
2use std::ops::*;
3
4/// Represents the three possible types of intersection between two ranges.
5#[derive(Debug, PartialEq)]
6pub enum Intersection {
7    /// The two ranges do not overlap at all.
8    Empty,
9
10    /// The two ranges overlap each other but none is contained within the other.
11    Overlap,
12
13    /// One range is fully contained in the other (they may be identical).
14    Full,
15}
16
17impl Intersection {
18    /// Checks if there is any intersection. Returns false only when the intersection is Empty.
19    pub fn is_any(&self) -> bool {
20        match self {
21            Intersection::Empty => false,
22            _ => true,
23        }
24    }
25}
26
27/// Extends the Intersection enum with additional cases specific to ranges, from the point of the first
28/// range.
29#[derive(Debug, PartialEq)]
30pub enum IntersectionExt {
31    /// One or the both of the ranges are empty, hence cannot intersect.
32    Empty,
33    /// The first range starts and ends before the second range, hence is fully less than.
34    Less,
35
36    /// The first range starts before the second is less, but overlaps with it with the end.
37    LessOverlap,
38
39    /// The first range is contained within the second range.
40    Within,
41
42    /// Two ranges are identical.
43    Same,
44
45    /// The first range contains the second range.
46    Over,
47
48    /// The first range ends after (greater) the first range, but overlaps with it.
49    GreaterOverlap,
50
51    /// The first range is after the second range, is fully greater than.
52    Greater,
53}
54
55impl IntersectionExt {
56    /// Converts an IntersectionExt instance into an Intersection instance.
57    pub fn intersection(&self) -> Intersection {
58        match self {
59            IntersectionExt::Empty => Intersection::Empty,
60            IntersectionExt::Less => Intersection::Empty,
61            IntersectionExt::LessOverlap => Intersection::Overlap,
62            IntersectionExt::Within => Intersection::Full,
63            IntersectionExt::Same => Intersection::Full,
64            IntersectionExt::Over => Intersection::Full,
65            IntersectionExt::GreaterOverlap => Intersection::Overlap,
66            IntersectionExt::Greater => Intersection::Empty,
67        }
68    }
69
70    /// Checks if there is any intersection.
71    pub fn is_any(&self) -> bool {
72        match self {
73            IntersectionExt::Empty |
74            IntersectionExt::Less |
75            IntersectionExt::Greater => false,
76            _ => true,
77        }
78    }
79
80    /// Checks if this range is contained within the other range. Identical is within as well.
81    pub fn is_within(&self) -> bool {
82        match self {
83            IntersectionExt::Within | IntersectionExt::Same => true,
84            _ => false,
85        }
86    }
87}
88
89/// A type implementing this trait can return the intersection between itself and another range.
90pub trait Intersect<T: PartialOrd, U: RangeBounds<T>>: RangeBounds<T> {
91    /// Return extended intersection between the two ranges, from the point of the first range.
92    fn intersect_ext(&self, other: &U) -> IntersectionExt;
93    /// Return the intersection between the two ranges.
94    fn intersect(&self, other: &U) -> Intersection;
95    /// Checks if the two ranges intersect.
96    fn does_intersect(&self, other:&U) -> bool;
97}
98
99macro_rules! empty_and_reverse {
100    ($a: ident, $b: ident, $fun: ident, $empty: expr) => {
101        if $a.start == $a.end || $b.start == $b.end {
102            return $empty;
103        }
104        if $a.start > $a.end {
105            return ($a.end .. $a.start).$fun($b);
106        }
107        if $b.start > $b.end {
108            return $a.$fun(&($b.end .. $b.start));
109        }
110    }
111}
112
113fn do_intersect_ext<T: PartialOrd>(a: &T, b: &T, x: &T, y: &T) -> IntersectionExt {
114    if b == y {
115        if a < x {
116            IntersectionExt::Over
117        } else if a > x {
118            IntersectionExt::Within
119        } else {
120            IntersectionExt::Same
121        }
122    } else if b < y {
123        if b <= x {
124            IntersectionExt::Less
125        } else if a < x {
126            IntersectionExt::LessOverlap
127        } else {
128            IntersectionExt::Within
129        }
130    } else if a < y {
131        if a <= x {
132            IntersectionExt::Over
133        } else {
134            IntersectionExt::GreaterOverlap
135        }
136    } else {
137        IntersectionExt::Greater
138    }
139}
140
141impl<T: PartialOrd + Copy> Intersect<T, Range<T>> for Range<T> {
142    /// Determines and returns the IntersectionExt between two ranges.
143    fn intersect_ext(&self, other: &Range<T>) -> IntersectionExt {
144        let (a, b) = match self.start.partial_cmp(&self.end) {
145            None | Some(Ordering::Equal) => return IntersectionExt::Empty,
146            Some(Ordering::Less) => (&self.start, &self.end),
147            Some(Ordering::Greater) => (&self.end, &self.start),
148        };
149        let (x, y) = match other.start.partial_cmp(&other.end) {
150            None | Some(Ordering::Equal) => return IntersectionExt::Empty,
151            Some(Ordering::Less) => (&other.start, &other.end),
152            Some(Ordering::Greater) => (&other.end, &other.start),
153        };
154        do_intersect_ext(a, b, x, y)
155    }
156
157    fn intersect(&self, other: &Range<T>) -> Intersection {
158        empty_and_reverse!(self, other, intersect, Intersection::Empty);
159        if self.end <= other.start || self.start >= other.end {
160            Intersection::Empty
161        } else {
162            match (self.start.partial_cmp(&other.start), self.end.partial_cmp(&other.end)) {
163                (None, _) => Intersection::Empty,
164                (_, None) => Intersection::Empty,
165                (Some(Ordering::Equal), _) => Intersection::Full,
166                (Some(Ordering::Less), Some(Ordering::Less)) => Intersection::Overlap,
167                (Some(Ordering::Less), _) => Intersection::Full,
168                (Some(Ordering::Greater), Some(Ordering::Greater)) => Intersection::Overlap,
169                (Some(Ordering::Greater), _) => Intersection::Full,
170            }
171        }
172    }
173
174    fn does_intersect(&self, other: &Range<T>) -> bool {
175        empty_and_reverse!(self, other, does_intersect, false);
176        if self.end <= other.start || self.start >= other.end {
177            false
178        } else {
179            match (self.start.partial_cmp(&other.start), self.end.partial_cmp(&other.end)) {
180                (None, _) => false,
181                (_, None) => false,
182                _ => true,
183            }
184        }
185    }
186}
187
188macro_rules! empty_and_reverse_a {
189    ($a: ident, $b: ident, $fun: ident, $empty: expr) => {
190        if $a.start == $a.end {
191            return $empty;
192        }
193        if $a.start > $a.end {
194            return ($a.end .. $a.start).$fun($b);
195        }
196    }
197}
198
199impl<T: PartialOrd + Copy> Intersect<T, RangeFrom<T>> for Range<T> {
200    /// Determines and returns the IntersectionExt between a bounded range and a range starting from a value.
201    fn intersect_ext(&self, other: &RangeFrom<T>) -> IntersectionExt {
202        empty_and_reverse_a!(self, other, intersect_ext, IntersectionExt::Empty);
203        if self.end <= other.start {
204            IntersectionExt::Less
205        } else if self.start >= other.start {
206            IntersectionExt::Within
207        } else {
208            IntersectionExt::LessOverlap
209        }
210    }
211
212    fn intersect(&self, other: &RangeFrom<T>) -> Intersection {
213        empty_and_reverse_a!(self, other, intersect, Intersection::Empty);
214        if self.end <= other.start {
215            Intersection::Empty
216        } else if self.start >= other.start {
217            Intersection::Full
218        } else {
219            Intersection::Overlap
220        }
221    }
222
223    fn does_intersect(&self, other: &RangeFrom<T>) -> bool {
224        empty_and_reverse_a!(self, other, does_intersect, false);
225        if self.end <= other.start {
226            false
227        } else {
228            true
229        }
230    }
231}
232
233impl<T: PartialOrd> Intersect<T, RangeFull> for Range<T> {
234    /// A range is always within a full range, so always return IntersectionFull::Within.
235    fn intersect_ext(&self, _: &RangeFull) -> IntersectionExt {
236        if self.start == self.end {
237            IntersectionExt::Empty
238        } else {
239            IntersectionExt::Within
240        }
241    }
242
243    fn intersect(&self, _: &RangeFull) -> Intersection {
244        if self.start == self.end {
245            Intersection::Empty
246        } else {
247
248            Intersection::Full
249        }
250    }
251
252    fn does_intersect(&self, _: &RangeFull) -> bool {
253        if self.start == self.end {
254            false
255        } else {
256            true
257        }
258    }
259}
260
261impl<T: PartialOrd + Copy> Intersect<T, RangeTo<T>> for Range<T> {
262    /// Determines and returns the IntersectionExt between a bounded range and a range ending at a value.
263    fn intersect_ext(&self, other: &RangeTo<T>) -> IntersectionExt {
264        empty_and_reverse_a!(self, other, intersect_ext, IntersectionExt::Empty);
265        if self.start >= other.end {
266            IntersectionExt::Greater
267        } else if self.end > other.end {
268            IntersectionExt::GreaterOverlap
269        } else {
270            IntersectionExt::Within
271        }
272    }
273
274    fn intersect(&self, other: &RangeTo<T>) -> Intersection {
275        empty_and_reverse_a!(self, other, intersect, Intersection::Empty);
276        if self.start >= other.end {
277            Intersection::Empty
278        } else if self.end > other.end {
279            Intersection::Overlap
280        } else {
281            Intersection::Full
282        }
283    }
284
285    fn does_intersect(&self, other: &RangeTo<T>) -> bool {
286        empty_and_reverse_a!(self, other, does_intersect, false);
287        if self.start >= other.end {
288            false
289        } else if self.end > other.end {
290            true
291        } else {
292            true
293        }
294    }
295}
296
297macro_rules! test_if_reverse {
298    ($a: expr, $b: expr, $x: expr, $y: expr, $empty: expr) => {{
299        let (a, b) = match $a.partial_cmp($b) {
300            None => return $empty,
301            Some(Ordering::Less) | Some(Ordering::Equal) => ($a, $b),
302            Some(Ordering::Greater) => ($b, $a),
303        };
304        let (x, y) = match $x.partial_cmp($y) {
305            None  => return $empty,
306            Some(Ordering::Less) | Some(Ordering::Equal) => ($x, $y),
307            Some(Ordering::Greater) => ($y, $x),
308        };
309        (a, b, x, y)
310    } }
311}
312
313macro_rules! try_unwrap {
314    ($a: expr, $or: expr) => {
315        match $a {
316            Some(a) => a,
317            None => return $or,
318        }
319    }
320}
321impl<T: PartialOrd + Copy> Intersect<T, RangeInclusive<T>> for RangeInclusive<T> {
322    fn intersect_ext(&self, other: &RangeInclusive<T>) -> IntersectionExt {
323        // no empty ranges as these are inclusive
324        let (a, b, x, y) = test_if_reverse!(self.start(), self.end(), other.start(), other.end(), IntersectionExt::Empty);
325        if b == y {
326            if a < x {
327                IntersectionExt::Over
328            } else if a > x {
329                IntersectionExt::Within
330            } else {
331                IntersectionExt::Same
332            }
333        } else if a == y {
334            IntersectionExt::GreaterOverlap
335        } else if b < y {
336            if b < x {
337                IntersectionExt::Less
338            } else if a < x {
339                IntersectionExt::LessOverlap
340            } else {
341                IntersectionExt::Within
342            }
343        } else if a < y {
344            if a <= x {
345                IntersectionExt::Over
346            } else {
347                IntersectionExt::GreaterOverlap
348            }
349        } else {
350            IntersectionExt::Greater
351        }
352    }
353
354    fn intersect(&self, other: &RangeInclusive<T>) -> Intersection {
355        // no empty ranges as these are inclusive
356        let (a, b, x, y) = test_if_reverse!(self.start(), self.end(), other.start(), other.end(), Intersection::Empty);
357        let ax = try_unwrap!(a.partial_cmp(&x), Intersection::Empty);
358        let by = try_unwrap!(b.partial_cmp(&y), Intersection::Empty);
359        let ay = try_unwrap!(a.partial_cmp(&y), Intersection::Empty);
360        let bx = try_unwrap!(b.partial_cmp(&x), Intersection::Empty);
361
362        match (ax, ay, bx, by) {
363            (_, Ordering::Greater, _ , _) => Intersection::Empty,
364            (_, _, Ordering::Less, _) => Intersection::Empty,
365            (Ordering::Equal, _,_,_) => Intersection::Full,
366            (_, _, _, Ordering::Equal) => Intersection::Full,
367            (Ordering::Less, _,_,Ordering::Greater) => Intersection::Full,
368            (Ordering::Greater, _, _, Ordering::Less) => Intersection::Full,
369            _ => Intersection::Overlap,
370        }
371    }
372
373    fn does_intersect(&self, other: &RangeInclusive<T>) -> bool {
374        let (a, b, x, y) = test_if_reverse!(self.start(), self.end(), other.start(), other.end(), false);
375        let ay = try_unwrap!(a.partial_cmp(&y), false);
376        let bx = try_unwrap!(b.partial_cmp(&x), false);
377
378        match (ay, bx) {
379            (Ordering::Greater, _) => false,
380            (_, Ordering::Less) => false,
381            _ => true,
382        }
383    }
384}
385
386#[cfg(test)]
387mod tests {
388    use super::*;
389
390    #[test]
391    fn range_intersect() {
392        // Overlapping cases
393        assert_eq!((5..10).intersect_ext(&(3..7)), IntersectionExt::GreaterOverlap);
394        assert_eq!((5..10).intersect_ext(&(8..15)), IntersectionExt::LessOverlap);
395        assert_eq!((10..5).intersect_ext(&(3..7)), IntersectionExt::GreaterOverlap);
396        assert_eq!((10..5).intersect_ext(&(8..15)), IntersectionExt::LessOverlap);
397        assert_eq!((10..5).intersect_ext(&(7..3)), IntersectionExt::GreaterOverlap);
398        assert_eq!((10..5).intersect_ext(&(15..8)), IntersectionExt::LessOverlap);
399
400        // Complete overlap/within
401        assert_eq!((5..10).intersect_ext(&(5..10)), IntersectionExt::Same);
402        assert_eq!((5..10).intersect_ext(&(4..11)), IntersectionExt::Within);
403        assert_eq!((5..10).intersect_ext(&(5..20)), IntersectionExt::Within);
404
405        // Containing
406        assert_eq!((5..10).intersect_ext(&(6..9)), IntersectionExt::Over);
407        assert_eq!((5..10).intersect_ext(&(5..6)), IntersectionExt::Over);
408        assert_eq!((5..10).intersect_ext(&(6..10)), IntersectionExt::Over);
409
410        // Completely below or above
411        assert_eq!((5..10).intersect_ext(&(10..15)), IntersectionExt::Less);
412        assert_eq!((5..10).intersect_ext(&(0..5)), IntersectionExt::Greater);
413
414        // Intersecting with empty ranges
415        assert_eq!((5..10).intersect_ext(&(5..5)), IntersectionExt::Empty);
416        assert_eq!((5..5).intersect_ext(&(3..7)), IntersectionExt::Empty);
417        assert_eq!((5..5).intersect_ext(&(6..6)), IntersectionExt::Empty);
418
419
420        assert_eq!((5..10).intersect(&(0..5)), Intersection::Empty);
421        assert_eq!((5..10).intersect(&(11..20)), Intersection::Empty);
422        assert_eq!((5..5).intersect(&(11..20)), Intersection::Empty);
423        assert_eq!((5..10).intersect(&(5..5)), Intersection::Empty);
424        assert_eq!((5..10).intersect(&(5..10)), Intersection::Full);
425        assert_eq!((5..10).intersect(&(4..10)), Intersection::Full);
426        assert_eq!((5..10).intersect(&(4..12)), Intersection::Full);
427        assert_eq!((5..10).intersect(&(5..12)), Intersection::Full);
428        assert_eq!((5..10).intersect(&(6..12)), Intersection::Overlap);
429        assert_eq!((5..10).intersect(&(4..8)), Intersection::Overlap);
430        assert_eq!((5..10).intersect(&(5..11)), Intersection::Full);
431
432
433        assert_eq!((5..10).does_intersect(&(5..10)), true);
434        assert_eq!((5..10).does_intersect(&(5..10)), true);
435        assert_eq!((5..5).does_intersect(&(5..10)), false);
436
437        assert_eq!((5..10).does_intersect(&(5..5)), false);
438        assert_eq!((5..10).does_intersect(&(5..10)), true);
439        assert_eq!((5..10).does_intersect(&(4..10)), true);
440        assert_eq!((5..10).does_intersect(&(4..12)), true);
441        assert_eq!((5..10).does_intersect(&(5..12)), true);
442        assert_eq!((5..10).does_intersect(&(6..12)), true);
443        assert_eq!((5..10).does_intersect(&(4..8)), true);
444        assert_eq!((5..10).does_intersect(&(5..11)), true);
445    }
446
447    #[test]
448    fn range_from_intersect() {
449        assert_eq!((1..10).intersect_ext(&(5..)), IntersectionExt::LessOverlap);
450        assert_eq!((1..10).intersect_ext(&(11..)), IntersectionExt::Less);
451        assert_eq!((1..10).intersect_ext(&(1..)), IntersectionExt::Within);
452        assert_eq!((1..10).intersect_ext(&(0..)), IntersectionExt::Within);
453        assert_eq!((1..10).intersect_ext(&(10..)), IntersectionExt::Less);
454
455        // reverse
456        assert_eq!((10..1).intersect_ext(&(5..)), IntersectionExt::LessOverlap);
457        assert_eq!((10..1).intersect_ext(&(11..)), IntersectionExt::Less);
458        assert_eq!((10..1).intersect_ext(&(1..)), IntersectionExt::Within);
459        assert_eq!((10..1).intersect_ext(&(0..)), IntersectionExt::Within);
460
461        assert_eq!((1..1).intersect_ext(&(0..)), IntersectionExt::Empty);
462
463
464        assert_eq!((1..10).intersect(&(10..)), Intersection::Empty);
465        assert_eq!((1..10).intersect(&(5..)), Intersection::Overlap);
466        assert_eq!((1..10).intersect(&(11..)), Intersection::Empty);
467        assert_eq!((1..10).intersect(&(1..)), Intersection::Full);
468        assert_eq!((1..10).intersect(&(0..)), Intersection::Full);
469        assert_eq!((1..1).intersect(&(0..)), Intersection::Empty);
470        assert_eq!((10..1).intersect(&(5..)), Intersection::Overlap);
471        assert_eq!((10..1).intersect(&(11..)), Intersection::Empty);
472        assert_eq!((10..1).intersect(&(1..)), Intersection::Full);
473        assert_eq!((10..1).intersect(&(0..)), Intersection::Full);
474
475
476        assert_eq!((1..10).does_intersect(&(10..)), false);
477        assert_eq!((1..10).does_intersect(&(5..)), true);
478        assert_eq!((1..10).does_intersect(&(11..)), false);
479        assert_eq!((1..10).does_intersect(&(1..)), true);
480        assert_eq!((1..10).does_intersect(&(0..)), true);
481        assert_eq!((1..1) .does_intersect(&(0..)), false);
482        assert_eq!((10..1).does_intersect(&(5..)), true);
483        assert_eq!((10..1).does_intersect(&(11..)), false);
484        assert_eq!((10..1).does_intersect(&(1..)), true);
485        assert_eq!((10..1).does_intersect(&(0..)), true);
486    }
487
488    #[test]
489    fn range_full_intersect() {
490        assert_eq!((1..10).intersect_ext(&..), IntersectionExt::Within);
491        assert_eq!((1..1).intersect_ext(&..), IntersectionExt::Empty);
492
493        assert_eq!((1..10).intersect(&..), Intersection::Full);
494        assert_eq!((1..1).intersect(&..), Intersection::Empty);
495
496        assert_eq!((1..10).does_intersect(&..), true);
497        assert_eq!((1..1).does_intersect(&..), false);
498    }
499
500    #[test]
501    fn range_to_intersect() {
502        assert_eq!((1..1).intersect_ext(&(..0)), IntersectionExt::Empty);
503        assert_eq!((1..10).intersect_ext(&(..0)), IntersectionExt::Greater);
504        assert_eq!((1..10).intersect_ext(&(..1)), IntersectionExt::Greater);
505        assert_eq!((1..10).intersect_ext(&(..2)), IntersectionExt::GreaterOverlap);
506        assert_eq!((1..10).intersect_ext(&(..10)), IntersectionExt::Within);
507        assert_eq!((1..10).intersect_ext(&(..11)), IntersectionExt::Within);
508
509        assert_eq!((10..1).intersect_ext(&(..0)), IntersectionExt::Greater);
510        assert_eq!((10..1).intersect_ext(&(..1)), IntersectionExt::Greater);
511        assert_eq!((10..1).intersect_ext(&(..2)), IntersectionExt::GreaterOverlap);
512        assert_eq!((10..1).intersect_ext(&(..10)), IntersectionExt::Within);
513        assert_eq!((10..1).intersect_ext(&(..11)), IntersectionExt::Within);
514
515        assert_eq!((1..1). intersect(&(..0)), Intersection::Empty);
516        assert_eq!((1..10).intersect(&(..0)), Intersection::Empty);
517        assert_eq!((1..10).intersect(&(..1)), Intersection::Empty);
518        assert_eq!((1..10).intersect(&(..2)), Intersection::Overlap);
519        assert_eq!((1..10).intersect(&(..10)), Intersection::Full);
520        assert_eq!((1..10).intersect(&(..11)), Intersection::Full);
521
522        assert_eq!((10..1).intersect(&(..0)), Intersection::Empty);
523        assert_eq!((10..1).intersect(&(..1)), Intersection::Empty);
524        assert_eq!((10..1).intersect(&(..2)), Intersection::Overlap);
525        assert_eq!((10..1).intersect(&(..10)), Intersection::Full);
526        assert_eq!((10..1).intersect(&(..11)), Intersection::Full);
527    }
528
529    #[test]
530    fn functions_test() {
531        assert_eq!(Intersection::Overlap.is_any(), true);
532        assert_eq!(Intersection::Empty.is_any(), false);
533        assert_eq!(IntersectionExt::Less.is_any(), false);
534        assert_eq!(IntersectionExt::LessOverlap.is_any(), true);
535        assert_eq!(IntersectionExt::Within.is_any(), true);
536        assert_eq!(IntersectionExt::Same.is_any(), true);
537        assert_eq!(IntersectionExt::Over.is_any(), true);
538        assert_eq!(IntersectionExt::GreaterOverlap.is_any(), true);
539        assert_eq!(IntersectionExt::Greater.is_any(), false);
540        assert_eq!(IntersectionExt::Less.is_within(), false);
541        assert_eq!(IntersectionExt::LessOverlap.is_within(), false);
542        assert_eq!(IntersectionExt::Within.is_within(), true);
543        assert_eq!(IntersectionExt::Same.is_within(), true);
544        assert_eq!(IntersectionExt::Over.is_within(), false);
545        assert_eq!(IntersectionExt::GreaterOverlap.is_within(), false);
546        assert_eq!(IntersectionExt::Greater.is_within(), false);
547    }
548
549    #[test]
550    fn range_inclusive_test() {
551        assert_eq!((10..=1).intersect_ext(&(15..=1)), IntersectionExt::Within);
552        assert_eq!((10..=1).intersect_ext(&(10..=1)), IntersectionExt::Same);
553        assert_eq!((10..=1).intersect_ext(&(9..=1)), IntersectionExt::Over);
554        assert_eq!((10..=1).intersect_ext(&(10..=9)), IntersectionExt::Over);
555        assert_eq!((10..=1).intersect_ext(&(10..=0)), IntersectionExt::Within);
556        assert_eq!((10..=1).intersect_ext(&(1..=0)), IntersectionExt::GreaterOverlap);
557        assert_eq!((10..=1).intersect_ext(&(0..=-1)), IntersectionExt::Greater);
558        assert_eq!((10..=1).intersect_ext(&(11..=10)), IntersectionExt::LessOverlap);
559        assert_eq!((10..=1).intersect_ext(&(12..=11)), IntersectionExt::Less);
560
561        assert_eq!((10..=1).intersect(&(15..=1)), Intersection::Full);
562        assert_eq!((10..=1).intersect(&(10..=1)), Intersection::Full);
563        assert_eq!((10..=1).intersect(&(9..=1)), Intersection::Full);
564        assert_eq!((10..=1).intersect(&(10..=9)), Intersection::Full);
565        assert_eq!((10..=1).intersect(&(10..=0)), Intersection::Full);
566        assert_eq!((10..=1).intersect(&(1..=0)), Intersection::Overlap);
567        assert_eq!((10..=1).intersect(&(0..=-1)), Intersection::Empty);
568        assert_eq!((10..=1).intersect(&(11..=10)), Intersection::Overlap);
569        assert_eq!((10..=1).intersect(&(12..=11)), Intersection::Empty);
570
571        assert_eq!((10..=1).does_intersect(&(15..=1)), true);
572        assert_eq!((10..=1).does_intersect(&(10..=1)), true);
573        assert_eq!((10..=1).does_intersect(&(9..=1)), true);
574        assert_eq!((10..=1).does_intersect(&(10..=9)), true);
575        assert_eq!((10..=1).does_intersect(&(10..=0)), true);
576        assert_eq!((10..=1).does_intersect(&(1..=0)), true);
577        assert_eq!((10..=1).does_intersect(&(0..=-1)), false);
578        assert_eq!((10..=1).does_intersect(&(11..=10)), true);
579        assert_eq!((10..=1).does_intersect(&(12..=11)), false);
580    }
581}