portion_rs/
interval.rs

1//! Holds the interval type and associated methods.
2
3use crate::impls::Item;
4use crate::iter::IntoIter;
5use crate::ops::Operations;
6use std::fmt::Display;
7
8/// The interval type, main type of this library.
9pub struct Interval<T: Item> {
10    pub(crate) lower: Option<T>,
11    pub(crate) upper: Option<T>,
12    pub(crate) itype: IntervalType,
13}
14
15#[derive(Eq, PartialEq, Copy, Clone)]
16pub(crate) enum IntervalType {
17    Open,
18    Closed,
19    Empty,
20    Singleton,
21    OpenClosed,
22    ClosedOpen,
23}
24
25impl<T: Item> PartialEq for Interval<T> {
26    fn eq(&self, other: &Self) -> bool {
27        self.to_string() == other.to_string()
28    }
29}
30
31impl<T: Item> Eq for Interval<T> {}
32
33impl<T: Item> Display for Interval<T> {
34    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35        if self.empty() {
36            return write!(f, "()");
37        };
38        use IntervalType::*;
39        match self.itype {
40            Open => write!(f, "({}, {})", self.lower(), self.upper()),
41            Closed => write!(f, "[{}, {}]", self.lower(), self.upper()),
42            Empty => write!(f, "()"),
43            Singleton => write!(f, "[{}]", self.lower()),
44            OpenClosed => write!(f, "({}, {}]", self.lower(), self.upper()),
45            ClosedOpen => write!(f, "[{}, {})", self.lower(), self.upper()),
46        }
47    }
48}
49
50impl<T: Item> IntoIterator for Interval<T> {
51    type Item = T;
52    type IntoIter = IntoIter<T>;
53
54    fn into_iter(self) -> Self::IntoIter {
55        use IntervalType::*;
56        let current = match self.itype {
57            Open | OpenClosed => Some(self.lower().next()),
58            _ => self.lower,
59        };
60
61        IntoIter {
62            current,
63            interval: self,
64        }
65    }
66}