1use alloc::{
2 rc::Rc,
3 string::{String, ToString},
4};
5use core::{
6 cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd},
7 ops::Bound::{self, Excluded, Included, Unbounded},
8};
9use num::Num;
10
11#[derive(Clone, Debug, Hash)]
46pub struct Interval<T: Ord> {
47 low: Rc<Bound<T>>,
48 high: Rc<Bound<T>>,
49}
50
51impl<T: Ord> Interval<T> {
52 pub fn new(low: Bound<T>, high: Bound<T>) -> Interval<T> {
77 let interval = Interval {
78 low: Rc::new(low),
79 high: Rc::new(high),
80 };
81
82 assert!(Interval::valid(&interval), "Interval is not valid");
83 interval
84 }
85
86 pub fn point(value: T) -> Interval<T> {
100 let low = Rc::new(Included(value));
101 let high = Rc::clone(&low);
102
103 let interval = Interval { low, high };
104
105 assert!(Interval::valid(&interval), "Interval is not valid");
106
107 interval
108 }
109
110 #[must_use]
123 pub fn duplicate(&self) -> Interval<T> {
124 Interval {
125 low: self.get_low(),
126 high: self.get_high(),
127 }
128 }
129
130 fn valid(interval: &Interval<T>) -> bool {
131 match (&interval.low(), &interval.high()) {
132 (Included(low), Included(high)) => low <= high,
133
134 (Included(low) | Excluded(low), Excluded(high)) | (Excluded(low), Included(high)) => {
135 low < high
136 }
137
138 _ => true,
139 }
140 }
141
142 #[must_use]
144 pub fn low(&self) -> &Bound<T> {
145 self.low.as_ref()
146 }
147
148 #[must_use]
150 pub fn get_low(&self) -> Rc<Bound<T>> {
151 Rc::clone(&self.low)
152 }
153
154 #[must_use]
156 pub fn high(&self) -> &Bound<T> {
157 self.high.as_ref()
158 }
159
160 #[must_use]
162 pub fn get_high(&self) -> Rc<Bound<T>> {
163 Rc::clone(&self.high)
164 }
165
166 #[must_use]
182 pub fn overlaps(first: &Interval<T>, second: &Interval<T>) -> bool {
183 let high: &Bound<T>;
184 let low: &Bound<T>;
185
186 if *first == *second {
187 return true;
188 } else if first < second {
189 low = second.low();
190 high = first.high();
191 } else {
192 low = first.low();
193 high = second.high();
194 }
195
196 match (low, high) {
197 (Included(low), Included(high)) => high >= low,
198 (Included(low) | Excluded(low), Excluded(high)) | (Excluded(low), Included(high)) => {
199 high > low
200 }
201 _ => true,
202 }
203 }
204
205 #[must_use]
218 pub fn contains(first: &Interval<T>, second: &Interval<T>) -> bool {
219 if Interval::overlaps(first, second) {
220 let overlap = Interval::get_overlap(first, second).unwrap();
221
222 overlap == *second
223 } else {
224 false
225 }
226 }
227
228 #[must_use]
242 pub fn get_overlap(first: &Interval<T>, second: &Interval<T>) -> Option<Interval<T>> {
243 if !Interval::overlaps(first, second) {
244 return None;
245 }
246
247 let low = match (&first.low(), &second.low()) {
248 (Included(low1) | Excluded(low1), Included(low2))
249 | (Excluded(low1), Excluded(low2)) => {
250 if low1 >= low2 {
251 Rc::clone(&first.low)
252 } else {
253 Rc::clone(&second.low)
254 }
255 }
256 (Included(low1), Excluded(low2)) => {
257 if low1 > low2 {
258 Rc::clone(&first.low)
259 } else {
260 Rc::clone(&second.low)
261 }
262 }
263 (Unbounded, Included(_) | Excluded(_)) => Rc::clone(&second.low),
264 (Included(_) | Excluded(_), Unbounded) => Rc::clone(&first.low),
265
266 (Unbounded, Unbounded) => Rc::new(Unbounded),
267 };
268
269 let high = match (&first.high(), &second.high()) {
270 (Included(high1) | Excluded(high1), Included(high2))
271 | (Excluded(high1), Excluded(high2)) => {
272 if high1 <= high2 {
273 Rc::clone(&first.high)
274 } else {
275 Rc::clone(&second.high)
276 }
277 }
278 (Included(high1), Excluded(high2)) => {
279 if high1 < high2 {
280 Rc::clone(&first.high)
281 } else {
282 Rc::clone(&second.high)
283 }
284 }
285 (Unbounded, Included(_) | Excluded(_)) => Rc::clone(&second.high),
286 (Included(_) | Excluded(_), Unbounded) => Rc::clone(&first.high),
287
288 (Unbounded, Unbounded) => Rc::new(Unbounded),
289 };
290
291 Some(Interval { low, high })
292 }
293}
294
295impl<T: Copy + Num + Ord> Interval<T> {
296 #[must_use]
299 pub fn span(&self) -> Option<T> {
300 match (&self.low(), &self.high()) {
301 (Included(low), Included(high)) => Some(*high + T::one() - *low),
302 (Included(low), Excluded(high)) | (Excluded(low), Included(high)) => Some(*high - *low),
303 (Excluded(low), Excluded(high)) => Some(*high - T::one() - *low),
304 _ => None,
305 }
306 }
307}
308
309impl<T: Ord + core::fmt::Display> core::fmt::Display for Interval<T> {
310 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
311 let low = match &self.low() {
312 Included(low) => format!("[{}", low),
313 Excluded(low) => format!("({}", low),
314 Unbounded => "(_".to_string(),
315 };
316
317 let high: String = match &self.high() {
318 Included(high) => format!("{}]", high),
319 Excluded(high) => format!("{})", high),
320 Unbounded => "_)".to_string(),
321 };
322
323 write!(f, "{},{}", low, high)
324 }
325}
326
327impl<T: Ord> PartialEq for Interval<T> {
328 fn eq(&self, other: &Self) -> bool {
329 self.low == other.low && self.high == other.high
330 }
331}
332
333impl<T: Ord> Eq for Interval<T> {}
334
335impl<T: Ord> PartialOrd for Interval<T> {
336 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
337 let mut result = match (&self.low(), &other.low()) {
339 (Included(low1), Included(low2)) | (Excluded(low1), Excluded(low2)) => {
340 if low1 < low2 {
341 Some(Ordering::Less)
342 } else if low1 == low2 {
343 None
344 } else {
345 Some(Ordering::Greater)
346 }
347 }
348 (Included(low1), Excluded(low2)) => {
349 if low1 <= low2 {
350 Some(Ordering::Less)
351 } else {
352 Some(Ordering::Greater)
353 }
354 }
355 (Excluded(low1), Included(low2)) => {
356 if low1 < low2 {
357 Some(Ordering::Less)
358 } else {
359 Some(Ordering::Greater)
360 }
361 }
362
363 (Unbounded, Included(_) | Excluded(_)) => Some(Ordering::Less),
364
365 (Included(_) | Excluded(_), Unbounded) => Some(Ordering::Greater),
366
367 (Unbounded, Unbounded) => None,
368 };
369
370 if result.is_none() {
372 result = match (&self.high(), &other.high()) {
373 (Included(high1), Included(high2)) | (Excluded(high1), Excluded(high2)) => {
374 if high1 < high2 {
375 Some(Ordering::Less)
376 } else if high1 == high2 {
377 Some(Ordering::Equal)
378 } else {
379 Some(Ordering::Greater)
380 }
381 }
382 (Included(high1), Excluded(high2)) => {
383 if high1 < high2 {
384 Some(Ordering::Less)
385 } else {
386 Some(Ordering::Greater)
387 }
388 }
389 (Excluded(high1), Included(high2)) => {
390 if high1 <= high2 {
391 Some(Ordering::Less)
392 } else {
393 Some(Ordering::Greater)
394 }
395 }
396 (Unbounded, Included(_) | Excluded(_)) => Some(Ordering::Greater),
397
398 (Included(_) | Excluded(_), Unbounded) => Some(Ordering::Less),
399
400 (Unbounded, Unbounded) => Some(Ordering::Equal),
401 };
402 }
403
404 result
405 }
406}
407
408impl<T: Ord> Ord for Interval<T> {
409 fn cmp(&self, other: &Self) -> Ordering {
410 self.partial_cmp(other).unwrap()
411 }
412}
413
414#[cfg(test)]
415mod tests {
416 use super::*;
417
418 #[test]
419 fn interval_valid_1() {
420 assert!(Interval::valid(&Interval::new(Included(2), Included(2))));
421 assert!(Interval::valid(&Interval::new(Excluded(2), Included(3))));
422 assert!(Interval::valid(&Interval::new(Included(2), Excluded(3))));
423 assert!(Interval::valid(&Interval::new(Excluded(2), Excluded(3))));
424
425 assert!(Interval::valid(&Interval::new(Unbounded, Included(1))));
426 assert!(Interval::valid(&Interval::new(Excluded(2), Unbounded)));
427 assert!(Interval::<usize>::valid(&Interval::new(
428 Unbounded, Unbounded
429 )));
430 }
431
432 #[test]
433 #[should_panic(expected = "Interval is not valid")]
434 fn interval_panic_new_1() {
435 assert!(!Interval::valid(&Interval::new(Included(2), Included(1))));
436 }
437
438 #[test]
439 #[should_panic(expected = "Interval is not valid")]
440 fn interval_panic_new_2() {
441 assert!(!Interval::valid(&Interval::new(Excluded(2), Included(1))));
442 }
443
444 #[test]
445 #[should_panic(expected = "Interval is not valid")]
446 fn interval_panic_new_3() {
447 assert!(!Interval::valid(&Interval::new(Included(2), Excluded(1))));
448 }
449
450 #[test]
451 #[should_panic(expected = "Interval is not valid")]
452 fn interval_panic_new_4() {
453 assert!(!Interval::valid(&Interval::new(Excluded(2), Excluded(1))));
454 }
455
456 #[test]
457 fn interval_compare_1() {
458 let interval1 = Interval::new(Included(2), Included(3));
459 let interval2 = Interval::new(Included(2), Excluded(3));
460 let interval3 = Interval::new(Excluded(2), Included(3));
461 let interval4 = Interval::new(Excluded(2), Excluded(3));
462
463 let interval5 = Interval::new(Unbounded, Excluded(3));
464 let interval6 = Interval::new(Excluded(2), Unbounded);
465 let interval7 = Interval::new(Unbounded, Excluded(3));
466 let interval8 = Interval::<usize>::new(Unbounded, Unbounded);
467
468 assert!(interval1 == interval1);
469 assert!(interval1 > interval2);
470 assert!(interval2 < interval1);
471 assert!(interval2 < interval3);
472 assert!(interval3 > interval4);
473 assert!(interval5 < interval6);
474 assert!(interval7 < interval6);
475 assert!(interval5 < interval8);
476 assert!(interval6 > interval8);
477 }
478
479 #[test]
480 fn interval_overlaps_1() {
481 let interval1 = Interval::new(Included(1), Included(3));
482 let interval2 = Interval::new(Included(2), Included(4));
483
484 assert!(Interval::overlaps(&interval1, &interval2));
485 }
486
487 #[test]
488 fn interval_overlaps_2() {
489 let interval1 = Interval::new(Included(1), Included(3));
490 let interval2 = Interval::new(Included(2), Excluded(3));
491
492 assert!(Interval::overlaps(&interval1, &interval2));
493 }
494
495 #[test]
496 fn interval_overlaps_3() {
497 let interval1 = Interval::new(Included(1), Included(3));
498 let interval2 = Interval::new(Excluded(1), Excluded(3));
499
500 assert!(Interval::overlaps(&interval1, &interval2));
501 }
502
503 #[test]
504 fn interval_overlaps_4() {
505 let interval1 = Interval::new(Included(1), Included(3));
506 let interval2 = Interval::new(Excluded(3), Excluded(4));
507
508 assert!(!Interval::overlaps(&interval1, &interval2));
509 }
510
511 #[test]
512 fn interval_overlaps_5() {
513 let interval1 = Interval::new(Included(1), Included(3));
514 let interval2 = Interval::new(Excluded(0), Excluded(1));
515
516 assert!(!Interval::overlaps(&interval1, &interval2));
517 }
518
519 #[test]
520 fn interval_overlaps_6() {
521 let interval1 = Interval::new(Included(1), Included(3));
522 let interval2 = Interval::new(Excluded(4), Excluded(5));
523
524 assert!(!Interval::overlaps(&interval1, &interval2));
525 }
526
527 #[test]
528 fn interval_overlaps_7() {
529 let interval1 = Interval::new(Unbounded, Included(3));
530 let interval2 = Interval::new(Excluded(1), Excluded(5));
531
532 assert!(Interval::overlaps(&interval1, &interval2));
533 }
534
535 #[test]
536 fn interval_overlaps_8() {
537 let interval1 = Interval::new(Included(1), Included(3));
538 let interval2 = Interval::new(Excluded(4), Unbounded);
539
540 assert!(!Interval::overlaps(&interval1, &interval2));
541 }
542
543 #[test]
544 fn interval_get_overlap_1() {
545 let interval1 = Interval::new(Included(1), Included(3));
546 let interval2 = Interval::new(Included(2), Included(4));
547
548 assert!(
549 Interval::get_overlap(&interval1, &interval2).unwrap()
550 == Interval::new(Included(2), Included(3))
551 );
552 }
553
554 #[test]
555 fn interval_get_overlap_2() {
556 let interval1 = Interval::new(Included(1), Excluded(3));
557 let interval2 = Interval::new(Included(2), Included(4));
558
559 assert!(
560 Interval::get_overlap(&interval1, &interval2).unwrap()
561 == Interval::new(Included(2), Excluded(3))
562 );
563 }
564
565 #[test]
566 fn interval_get_overlap_3() {
567 let interval1 = Interval::new(Included(1), Excluded(3));
568 let interval2 = Interval::new(Included(2), Included(3));
569
570 assert!(
571 Interval::get_overlap(&interval1, &interval2).unwrap()
572 == Interval::new(Included(2), Excluded(3))
573 );
574 }
575
576 #[test]
577 fn interval_get_overlap_4() {
578 let interval1 = Interval::new(Excluded(1), Excluded(3));
579 let interval2 = Interval::new(Included(1), Included(4));
580
581 assert!(
582 Interval::get_overlap(&interval1, &interval2).unwrap()
583 == Interval::new(Excluded(1), Excluded(3))
584 );
585 }
586
587 #[test]
588 fn interval_get_overlap_5() {
589 let interval1 = Interval::new(Unbounded, Excluded(3));
590 let interval2 = Interval::new(Included(1), Included(2));
591
592 assert!(
593 Interval::get_overlap(&interval1, &interval2).unwrap()
594 == Interval::new(Included(1), Included(2))
595 );
596 }
597
598 #[test]
599 fn interval_get_overlap_6() {
600 let interval1 = Interval::new(Unbounded, Excluded(3));
601 let interval2 = Interval::new(Unbounded, Included(2));
602
603 assert!(
604 Interval::get_overlap(&interval1, &interval2).unwrap()
605 == Interval::new(Unbounded, Included(2))
606 );
607 }
608
609 #[test]
610 fn interval_get_overlap_7() {
611 let interval1 = Interval::new(Excluded(2), Excluded(3));
612 let interval2 = Interval::new(Unbounded, Included(3));
613
614 assert!(
615 Interval::get_overlap(&interval1, &interval2).unwrap()
616 == Interval::new(Excluded(2), Excluded(3))
617 );
618 }
619
620 #[test]
621 fn interval_get_overlap_8() {
622 let interval1 = Interval::new(Excluded(2), Unbounded);
623 let interval2 = Interval::new(Unbounded, Unbounded);
624
625 assert!(
626 Interval::get_overlap(&interval1, &interval2).unwrap()
627 == Interval::new(Excluded(2), Unbounded)
628 );
629 }
630
631 #[test]
632 fn interval_get_overlap_9() {
633 let interval1 = Interval::new(Excluded(2), Included(3));
634 let interval2 = Interval::new(Excluded(3), Included(4));
635
636 assert!(Interval::get_overlap(&interval1, &interval2).is_none());
637 }
638
639 #[test]
640 fn interval_get_overlap_10() {
641 let interval1 = Interval::new(Excluded(2), Included(3));
642 let interval2 = Interval::new(Included(4), Included(4));
643
644 assert!(Interval::get_overlap(&interval1, &interval2).is_none());
645 }
646
647 #[test]
648 fn interval_get_overlap_11() {
649 let interval1 = Interval::new(Included(3), Included(4));
650 let interval2 = Interval::new(Included(2), Included(3));
651
652 assert!(
653 Interval::get_overlap(&interval1, &interval2).unwrap()
654 == Interval::new(Included(3), Included(3))
655 );
656 }
657
658 #[test]
659 fn interval_contains_1() {
660 let interval1 = Interval::new(Included(1), Included(4));
661 let interval2 = Interval::new(Included(2), Included(3));
662
663 assert!(Interval::contains(&interval1, &interval2));
664 }
665
666 #[test]
667 fn interval_contains_2() {
668 let interval1 = Interval::new(Included(1), Included(4));
669 let interval2 = Interval::new(Excluded(1), Included(3));
670
671 assert!(Interval::contains(&interval1, &interval2));
672 }
673
674 #[test]
675 fn interval_contains_3() {
676 let interval1 = Interval::new(Included(1), Included(4));
677 let interval2 = Interval::new(Included(1), Included(3));
678
679 assert!(Interval::contains(&interval1, &interval2));
680 }
681
682 #[test]
683 fn interval_contains_4() {
684 let interval1 = Interval::new(Included(1), Included(4));
685 let interval2 = Interval::new(Included(2), Excluded(4));
686
687 assert!(Interval::contains(&interval1, &interval2));
688 }
689
690 #[test]
691 fn interval_contains_5() {
692 let interval1 = Interval::new(Included(1), Included(4));
693 let interval2 = Interval::new(Included(2), Included(4));
694
695 assert!(Interval::contains(&interval1, &interval2));
696 }
697
698 #[test]
699 fn interval_span_1() {
700 let interval1 = Interval::new(Included(2), Included(3));
701 let interval2 = Interval::new(Included(2), Excluded(3));
702 let interval3 = Interval::new(Excluded(2), Included(3));
703 let interval4 = Interval::new(Excluded(2), Excluded(3));
704
705 let interval5 = Interval::new(Unbounded, Excluded(3));
706 let interval6 = Interval::new(Excluded(2), Unbounded);
707 let interval7 = Interval::new(Unbounded, Excluded(3));
708 let interval8 = Interval::<usize>::new(Unbounded, Unbounded);
709
710 assert_eq!(interval1.span(), Some(2));
711 assert_eq!(interval2.span(), Some(1));
712 assert_eq!(interval3.span(), Some(1));
713 assert_eq!(interval4.span(), Some(0));
714 assert_eq!(interval5.span(), None);
715 assert_eq!(interval6.span(), None);
716 assert_eq!(interval7.span(), None);
717 assert_eq!(interval8.span(), None);
718 }
719}