1use crate::impls::Item;
4use crate::iter::IntoIter;
5use crate::ops::Operations;
6use std::fmt::Display;
7
8pub 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}