Skip to main content

allen_intervals/interval/
interval_to.rs

1use core::ops::{RangeTo, RangeToInclusive};
2
3use crate::{
4    Contains, Equals, Finishes, Interval, IntervalFrom, IntervalFull, Meets, NonEmpty, Overlaps,
5    Precedes, Starts,
6};
7
8/// An interval only bounded exclusively, or inclusively above (`..end`, or `..=end`).
9///
10/// The RangeTo ..end contains all values with `x < end`, if `T` is a discrete domain,
11/// or `x <= end`, if `T` is a continuous domain.
12#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
13pub struct IntervalTo<T> {
14    /// The upper bound of the interval (exclusive, or inclusive).
15    pub end: T,
16}
17
18impl<T> From<RangeTo<T>> for IntervalTo<T> {
19    fn from(value: RangeTo<T>) -> Self {
20        Self { end: value.end }
21    }
22}
23
24impl<T> From<IntervalTo<T>> for RangeTo<T> {
25    fn from(value: IntervalTo<T>) -> Self {
26        ..(value.end)
27    }
28}
29
30impl<T> From<RangeToInclusive<T>> for IntervalTo<T> {
31    fn from(value: RangeToInclusive<T>) -> Self {
32        let end = value.end;
33        Self { end }
34    }
35}
36
37impl<T> From<IntervalTo<T>> for RangeToInclusive<T> {
38    fn from(value: IntervalTo<T>) -> Self {
39        ..=(value.end)
40    }
41}
42
43// IntervalTo<T> vs. IntervalFull
44
45impl<T> Precedes<NonEmpty<IntervalFull>> for NonEmpty<IntervalTo<T>> {}
46
47impl<T> Meets<NonEmpty<IntervalFull>> for NonEmpty<IntervalTo<T>> {}
48
49impl<T> Overlaps<NonEmpty<IntervalFull>> for NonEmpty<IntervalTo<T>> {}
50
51impl<T> Starts<NonEmpty<IntervalFull>> for NonEmpty<IntervalTo<T>> {}
52
53impl<T> Contains<NonEmpty<IntervalFull>> for NonEmpty<IntervalTo<T>> {}
54
55impl<T> Finishes<NonEmpty<IntervalFull>> for NonEmpty<IntervalTo<T>> {}
56
57impl<T> Equals<NonEmpty<IntervalFull>> for NonEmpty<IntervalTo<T>> {}
58
59// IntervalTo<T> vs. IntervalTo
60
61impl<T> Precedes<NonEmpty<IntervalTo<T>>> for NonEmpty<IntervalTo<T>> {}
62
63impl<T> Meets<NonEmpty<IntervalTo<T>>> for NonEmpty<IntervalTo<T>> {}
64
65impl<T> Overlaps<NonEmpty<IntervalTo<T>>> for NonEmpty<IntervalTo<T>> {}
66
67impl<T> Starts<NonEmpty<IntervalTo<T>>> for NonEmpty<IntervalTo<T>>
68where
69    T: PartialOrd,
70{
71    fn starts(&self, other: &NonEmpty<IntervalTo<T>>) -> bool {
72        self.0.end < other.0.end
73    }
74}
75
76impl<T> Contains<NonEmpty<IntervalTo<T>>> for NonEmpty<IntervalTo<T>> {}
77
78impl<T> Finishes<NonEmpty<IntervalTo<T>>> for NonEmpty<IntervalTo<T>> {}
79
80impl<T> Equals<NonEmpty<IntervalTo<T>>> for NonEmpty<IntervalTo<T>>
81where
82    T: PartialOrd,
83{
84    fn equals(&self, other: &NonEmpty<IntervalTo<T>>) -> bool {
85        self == other
86    }
87}
88
89// IntervalTo<T> vs. IntervalFrom
90
91impl<T> Precedes<NonEmpty<IntervalFrom<T>>> for NonEmpty<IntervalTo<T>>
92where
93    T: PartialOrd,
94{
95    fn precedes(&self, other: &NonEmpty<IntervalFrom<T>>) -> bool {
96        self.0.end < other.0.start
97    }
98}
99
100impl<T> Meets<NonEmpty<IntervalFrom<T>>> for NonEmpty<IntervalTo<T>>
101where
102    T: PartialOrd,
103{
104    fn meets(&self, other: &NonEmpty<IntervalFrom<T>>) -> bool {
105        self.0.end == other.0.start
106    }
107}
108
109impl<T> Overlaps<NonEmpty<IntervalFrom<T>>> for NonEmpty<IntervalTo<T>>
110where
111    T: PartialOrd,
112{
113    fn overlaps(&self, other: &NonEmpty<IntervalFrom<T>>) -> bool {
114        self.0.end > other.0.start
115    }
116}
117
118impl<T> Starts<NonEmpty<IntervalFrom<T>>> for NonEmpty<IntervalTo<T>> {}
119
120impl<T> Contains<NonEmpty<IntervalFrom<T>>> for NonEmpty<IntervalTo<T>> {}
121
122impl<T> Finishes<NonEmpty<IntervalFrom<T>>> for NonEmpty<IntervalTo<T>> {}
123
124impl<T> Equals<NonEmpty<IntervalFrom<T>>> for NonEmpty<IntervalTo<T>> {}
125
126// IntervalTo<T> vs. Interval
127
128impl<T> Precedes<NonEmpty<Interval<T>>> for NonEmpty<IntervalTo<T>>
129where
130    T: PartialOrd,
131{
132    fn precedes(&self, other: &NonEmpty<Interval<T>>) -> bool {
133        self.0.end < other.0.start
134    }
135}
136
137impl<T> Meets<NonEmpty<Interval<T>>> for NonEmpty<IntervalTo<T>>
138where
139    T: PartialOrd,
140{
141    fn meets(&self, other: &NonEmpty<Interval<T>>) -> bool {
142        self.0.end == other.0.start
143    }
144}
145
146impl<T> Overlaps<NonEmpty<Interval<T>>> for NonEmpty<IntervalTo<T>>
147where
148    T: PartialOrd,
149{
150    fn overlaps(&self, other: &NonEmpty<Interval<T>>) -> bool {
151        (self.0.end > other.0.start) && (self.0.end < other.0.end)
152    }
153}
154
155impl<T> Starts<NonEmpty<Interval<T>>> for NonEmpty<IntervalTo<T>> {}
156
157impl<T> Contains<NonEmpty<Interval<T>>> for NonEmpty<IntervalTo<T>>
158where
159    T: PartialOrd,
160{
161    fn contains(&self, other: &NonEmpty<Interval<T>>) -> bool {
162        self.0.end > other.0.end
163    }
164}
165
166impl<T> Finishes<NonEmpty<Interval<T>>> for NonEmpty<IntervalTo<T>> {}
167
168impl<T> Equals<NonEmpty<Interval<T>>> for NonEmpty<IntervalTo<T>> {}