Skip to main content

allen_intervals/
bounds.rs

1use crate::{
2    interval::{Interval, IntervalFrom, IntervalFull, IntervalTo},
3    NonEmpty,
4};
5
6/// An endpoint of an interval of time.
7#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
8pub enum Bound<T> {
9    /// A finite endpoint.
10    ///
11    /// Indicates that there is a bound in this direction.
12    Bounded(T),
13    /// An infinite endpoint.
14    ///
15    /// Indicates that there is no bound in this direction.
16    Unbounded,
17}
18
19/// The endpoints of an interval of time.
20#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
21pub struct Bounds<T> {
22    /// Start index bound.
23    ///
24    /// Returns the start value as a Bound.
25    pub start: Bound<T>,
26
27    /// End index bound.
28    ///
29    /// Returns the end value as a Bound.
30    pub end: Bound<T>,
31}
32
33/// `IntervalBounds` is implemented by the crate's built-in interval types.
34pub trait IntervalBounds<T> {
35    /// Start index bound.
36    ///
37    /// Returns the start value as a [`Bound<T>`].
38    fn start_bound(&self) -> Bound<T>;
39
40    /// End index bound.
41    ///
42    /// Returns the end value as a [`Bound<T>`].
43    fn end_bound(&self) -> Bound<T>;
44
45    /// Index bounds.
46    ///
47    /// Returns the start end end bounds as a [`Bounds<T>`].
48    fn bounds(&self) -> Bounds<T> {
49        Bounds {
50            start: self.start_bound(),
51            end: self.end_bound(),
52        }
53    }
54}
55
56impl<I, T> IntervalBounds<T> for NonEmpty<I>
57where
58    I: IntervalBounds<T>,
59{
60    fn start_bound(&self) -> Bound<T> {
61        self.0.start_bound()
62    }
63
64    fn end_bound(&self) -> Bound<T> {
65        self.0.end_bound()
66    }
67}
68
69impl<T> IntervalBounds<T> for Interval<T>
70where
71    T: Copy,
72{
73    fn start_bound(&self) -> Bound<T> {
74        Bound::Bounded(self.start)
75    }
76
77    fn end_bound(&self) -> Bound<T> {
78        Bound::Bounded(self.end)
79    }
80}
81
82impl<T> IntervalBounds<T> for IntervalFrom<T>
83where
84    T: Copy,
85{
86    fn start_bound(&self) -> Bound<T> {
87        Bound::Bounded(self.start)
88    }
89
90    fn end_bound(&self) -> Bound<T> {
91        Bound::Unbounded
92    }
93}
94
95impl<T> IntervalBounds<T> for IntervalTo<T>
96where
97    T: Copy,
98{
99    fn start_bound(&self) -> Bound<T> {
100        Bound::Unbounded
101    }
102
103    fn end_bound(&self) -> Bound<T> {
104        Bound::Bounded(self.end)
105    }
106}
107
108impl<T> IntervalBounds<T> for IntervalFull {
109    fn start_bound(&self) -> Bound<T> {
110        Bound::Unbounded
111    }
112
113    fn end_bound(&self) -> Bound<T> {
114        Bound::Unbounded
115    }
116}