1 // RangeBounds support for older Rust versions.
2 
3 use lib::ops::{Range, RangeFrom, RangeTo, RangeFull};
4 use super::bound::*;
5 
6 #[cfg(has_full_range_inclusive)]
7 use lib::ops::{RangeInclusive, RangeToInclusive};
8 
9 //  The compiler does not have RangeBounds defined, this is code
10 //  adopted from Rust:
11 //      https://doc.rust-lang.org/src/core/ops/range.rs.html
12 //
13 //  All copyright for the remainder of this file remains with the
14 //  Rust contributors:
15 //      https://github.com/rust-lang/rust/blob/master/COPYRIGHT
16 
17 #[cfg(has_range_bounds)]
18 pub use lib::ops::RangeBounds;
19 
20 #[cfg(not(has_range_bounds))]
21 pub trait RangeBounds<T: ?Sized> {
22     /// Start index bound.
start_bound(&self) -> Bound<&T>23     fn start_bound(&self) -> Bound<&T>;
24 
25     /// End index bound.
end_bound(&self) -> Bound<&T>26     fn end_bound(&self) -> Bound<&T>;
27 
28     /// Detect if item is in range.
contains<U>(&self, item: &U) -> bool where T: PartialOrd<U>, U: ?Sized + PartialOrd<T>,29     fn contains<U>(&self, item: &U) -> bool
30     where
31         T: PartialOrd<U>,
32         U: ?Sized + PartialOrd<T>,
33     {
34         (match self.start_bound() {
35             Included(ref start) => *start <= item,
36             Excluded(ref start) => *start < item,
37             Unbounded => true,
38         }) && (match self.end_bound() {
39             Included(ref end) => item <= *end,
40             Excluded(ref end) => item < *end,
41             Unbounded => true,
42         })
43     }
44 }
45 
46 #[cfg(not(has_range_bounds))]
47 impl<T: ?Sized> RangeBounds<T> for RangeFull {
start_bound(&self) -> Bound<&T>48     fn start_bound(&self) -> Bound<&T> {
49         Unbounded
50     }
end_bound(&self) -> Bound<&T>51     fn end_bound(&self) -> Bound<&T> {
52         Unbounded
53     }
54 }
55 
56 #[cfg(not(has_range_bounds))]
57 impl<T> RangeBounds<T> for RangeFrom<T> {
start_bound(&self) -> Bound<&T>58     fn start_bound(&self) -> Bound<&T> {
59         Included(&self.start)
60     }
end_bound(&self) -> Bound<&T>61     fn end_bound(&self) -> Bound<&T> {
62         Unbounded
63     }
64 }
65 
66 #[cfg(not(has_range_bounds))]
67 impl<T> RangeBounds<T> for RangeTo<T> {
start_bound(&self) -> Bound<&T>68     fn start_bound(&self) -> Bound<&T> {
69         Unbounded
70     }
end_bound(&self) -> Bound<&T>71     fn end_bound(&self) -> Bound<&T> {
72         Excluded(&self.end)
73     }
74 }
75 
76 #[cfg(not(has_range_bounds))]
77 impl<T> RangeBounds<T> for Range<T> {
start_bound(&self) -> Bound<&T>78     fn start_bound(&self) -> Bound<&T> {
79         Included(&self.start)
80     }
end_bound(&self) -> Bound<&T>81     fn end_bound(&self) -> Bound<&T> {
82         Excluded(&self.end)
83     }
84 }
85 
86 #[cfg(all(not(has_range_bounds), has_full_range_inclusive))]
87 impl<T> RangeBounds<T> for RangeInclusive<T> {
start_bound(&self) -> Bound<&T>88     fn start_bound(&self) -> Bound<&T> {
89         Included(self.start())
90     }
end_bound(&self) -> Bound<&T>91     fn end_bound(&self) -> Bound<&T> {
92         Included(self.end())
93     }
94 }
95 
96 #[cfg(all(not(has_range_bounds), has_full_range_inclusive))]
97 impl<T> RangeBounds<T> for RangeToInclusive<T> {
start_bound(&self) -> Bound<&T>98     fn start_bound(&self) -> Bound<&T> {
99         Unbounded
100     }
end_bound(&self) -> Bound<&T>101     fn end_bound(&self) -> Bound<&T> {
102         Included(&self.end)
103     }
104 }
105