1// Wrappers to allow storing (and sorting/searching)
2// ranges as the keys of a `BTreeMap`.
3//
4// This wraps the range in two layers: one that lets us
5// order ranges by their start (`RangeStartWrapper`),
6// and then within that, one that lets us order them by
7// their end (`RangeEndWrapper`). Ordinarily we'll use
8// the former, but there are a couple of cases where we
9// want to be able to do the latter for performance/convenience.
10//
11// This is made possible by a sneaky `Borrow` implementation
12// which skirts the law about the borrowed representation
13// having identical implementations of `Ord` etc., but shouldn't
14// be a problem in practice because users of the crate can't
15// access these special wrappers, and we are careful to uphold
16// invariants that prevent observing any states where the
17// differing implementations would produce different results.
18//
19// Specifically, we maintain the invariants
20// that the order of range starts is the same as the order
21// of range ends, and that no two stored ranges have the
22// same start or end as each other.
23//
24// NOTE: Be very careful not to accidentally use these
25// if you really do want to compare equality of the
26// inner range!
2728use core::cmp::Ordering;
29use core::ops::{Deref, Range, RangeInclusive};
3031//
32// Range start wrapper
33//
3435#[derive(Debug, Clone)]
36pub struct RangeStartWrapper<T> {
37pub end_wrapper: RangeEndWrapper<T>,
38}
3940impl<T> RangeStartWrapper<T> {
41pub fn new(range: Range<T>) -> RangeStartWrapper<T> {
42 RangeStartWrapper {
43 end_wrapper: RangeEndWrapper::new(range),
44 }
45 }
46}
4748impl<T> PartialEq for RangeStartWrapper<T>
49where
50T: PartialEq,
51{
52fn eq(&self, other: &RangeStartWrapper<T>) -> bool {
53self.start == other.start
54 }
55}
5657impl<T> Eq for RangeStartWrapper<T> where T: Eq {}
5859impl<T> Ord for RangeStartWrapper<T>
60where
61T: Ord,
62{
63fn cmp(&self, other: &RangeStartWrapper<T>) -> Ordering {
64self.start.cmp(&other.start)
65 }
66}
6768impl<T> PartialOrd for RangeStartWrapper<T>
69where
70T: PartialOrd,
71{
72fn partial_cmp(&self, other: &RangeStartWrapper<T>) -> Option<Ordering> {
73self.start.partial_cmp(&other.start)
74 }
75}
7677impl<T> core::borrow::Borrow<RangeEndWrapper<T>> for RangeStartWrapper<T> {
78fn borrow(&self) -> &RangeEndWrapper<T> {
79&self.end_wrapper
80 }
81}
8283// Avoid the need to tediously plumb through the layers of wrapper structs
84// when you're just trying to access members of the inner range itself.
85impl<T> Deref for RangeStartWrapper<T> {
86type Target = RangeEndWrapper<T>;
8788fn deref(&self) -> &Self::Target {
89&self.end_wrapper
90 }
91}
9293//
94// Range end wrapper
95//
9697#[derive(Debug, Clone)]
98pub struct RangeEndWrapper<T> {
99pub range: Range<T>,
100}
101102impl<T> RangeEndWrapper<T> {
103pub fn new(range: Range<T>) -> RangeEndWrapper<T> {
104 RangeEndWrapper { range }
105 }
106}
107108impl<T> PartialEq for RangeEndWrapper<T>
109where
110T: PartialEq,
111{
112fn eq(&self, other: &RangeEndWrapper<T>) -> bool {
113self.end == other.end
114 }
115}
116117impl<T> Eq for RangeEndWrapper<T> where T: Eq {}
118119impl<T> Ord for RangeEndWrapper<T>
120where
121T: Ord,
122{
123fn cmp(&self, other: &RangeEndWrapper<T>) -> Ordering {
124self.end.cmp(&other.end)
125 }
126}
127128impl<T> PartialOrd for RangeEndWrapper<T>
129where
130T: PartialOrd,
131{
132fn partial_cmp(&self, other: &RangeEndWrapper<T>) -> Option<Ordering> {
133self.end.partial_cmp(&other.end)
134 }
135}
136137// Avoid the need to tediously plumb through the layers of wrapper structs
138// when you're just trying to access members of the inner range itself.
139impl<T> Deref for RangeEndWrapper<T> {
140type Target = Range<T>;
141142fn deref(&self) -> &Self::Target {
143&self.range
144 }
145}
146147//
148// RangeInclusive start wrapper
149//
150151#[derive(Eq, Debug, Clone)]
152pub struct RangeInclusiveStartWrapper<T> {
153pub end_wrapper: RangeInclusiveEndWrapper<T>,
154}
155156impl<T> RangeInclusiveStartWrapper<T> {
157pub fn new(range: RangeInclusive<T>) -> RangeInclusiveStartWrapper<T> {
158 RangeInclusiveStartWrapper {
159 end_wrapper: RangeInclusiveEndWrapper::new(range),
160 }
161 }
162}
163164impl<T> PartialEq for RangeInclusiveStartWrapper<T>
165where
166T: PartialEq,
167{
168fn eq(&self, other: &RangeInclusiveStartWrapper<T>) -> bool {
169self.start() == other.start()
170 }
171}
172173impl<T> Ord for RangeInclusiveStartWrapper<T>
174where
175T: Ord,
176{
177fn cmp(&self, other: &RangeInclusiveStartWrapper<T>) -> Ordering {
178self.start().cmp(other.start())
179 }
180}
181182impl<T> PartialOrd for RangeInclusiveStartWrapper<T>
183where
184T: PartialOrd,
185{
186fn partial_cmp(&self, other: &RangeInclusiveStartWrapper<T>) -> Option<Ordering> {
187self.start().partial_cmp(other.start())
188 }
189}
190191impl<T> core::borrow::Borrow<RangeInclusiveEndWrapper<T>> for RangeInclusiveStartWrapper<T> {
192fn borrow(&self) -> &RangeInclusiveEndWrapper<T> {
193&self.end_wrapper
194 }
195}
196197// Avoid the need to tediously plumb through the layers of wrapper structs
198// when you're just trying to access members of the inner range itself.
199impl<T> Deref for RangeInclusiveStartWrapper<T> {
200type Target = RangeInclusiveEndWrapper<T>;
201202fn deref(&self) -> &Self::Target {
203&self.end_wrapper
204 }
205}
206207//
208// RangeInclusive end wrapper
209//
210211#[derive(Eq, Debug, Clone)]
212pub struct RangeInclusiveEndWrapper<T> {
213pub range: RangeInclusive<T>,
214}
215216impl<T> RangeInclusiveEndWrapper<T> {
217pub fn new(range: RangeInclusive<T>) -> RangeInclusiveEndWrapper<T> {
218 RangeInclusiveEndWrapper { range }
219 }
220}
221222impl<T> PartialEq for RangeInclusiveEndWrapper<T>
223where
224T: PartialEq,
225{
226fn eq(&self, other: &RangeInclusiveEndWrapper<T>) -> bool {
227self.end() == other.end()
228 }
229}
230231impl<T> Ord for RangeInclusiveEndWrapper<T>
232where
233T: Ord,
234{
235fn cmp(&self, other: &RangeInclusiveEndWrapper<T>) -> Ordering {
236self.end().cmp(other.end())
237 }
238}
239240impl<T> PartialOrd for RangeInclusiveEndWrapper<T>
241where
242T: PartialOrd,
243{
244fn partial_cmp(&self, other: &RangeInclusiveEndWrapper<T>) -> Option<Ordering> {
245self.end().partial_cmp(other.end())
246 }
247}
248249// Avoid the need to tediously plumb through the layers of wrapper structs
250// when you're just trying to access members of the inner range itself.
251impl<T> Deref for RangeInclusiveEndWrapper<T> {
252type Target = RangeInclusive<T>;
253254fn deref(&self) -> &Self::Target {
255&self.range
256 }
257}