|
16 | 16 |
|
17 | 17 | use std::cmp::Ordering;
|
18 | 18 | use std::fmt;
|
| 19 | +use std::ops::{Bound, RangeBounds}; |
19 | 20 |
|
20 | 21 | use crate::internal::small_vec::SmallVec;
|
21 | 22 | use crate::version::Version;
|
@@ -85,6 +86,31 @@ impl<V: Version> Range<V> {
|
85 | 86 | Self::none()
|
86 | 87 | }
|
87 | 88 | }
|
| 89 | + |
| 90 | + /// Construct a simple range from anything that impls `RangeBounds` like `v1..v2` |
| 91 | + pub fn from_range_bounds<'a, R, IV: 'a>(bounds: &'a R) -> Self |
| 92 | + where |
| 93 | + R: RangeBounds<IV>, |
| 94 | + &'a IV: Into<V>, |
| 95 | + { |
| 96 | + let start = match bounds.start_bound() { |
| 97 | + Bound::Included(s) => s.into(), |
| 98 | + Bound::Excluded(s) => s.into().bump(), |
| 99 | + Bound::Unbounded => V::lowest(), |
| 100 | + }; |
| 101 | + let end = match bounds.end_bound() { |
| 102 | + Bound::Included(e) => Some(e.into().bump()), |
| 103 | + Bound::Excluded(e) => Some(e.into()), |
| 104 | + Bound::Unbounded => None, |
| 105 | + }; |
| 106 | + if end.is_some() && end.as_ref() <= Some(&start) { |
| 107 | + Self::none() |
| 108 | + } else { |
| 109 | + Self { |
| 110 | + segments: SmallVec::one((start, end)), |
| 111 | + } |
| 112 | + } |
| 113 | + } |
88 | 114 | }
|
89 | 115 |
|
90 | 116 | // Set operations.
|
@@ -260,6 +286,23 @@ impl<V: Version> Range<V> {
|
260 | 286 | pub fn lowest_version(&self) -> Option<V> {
|
261 | 287 | self.segments.first().map(|(start, _)| start).cloned()
|
262 | 288 | }
|
| 289 | + |
| 290 | + /// Conver to somthing that can be used with BTreeMap::range |
| 291 | + /// All versions contained in self, will be in the output, |
| 292 | + /// but there may be versions in the output that are not contained in self. |
| 293 | + /// returns None if the range is empty. |
| 294 | + pub fn as_range_bounds(&self) -> Option<impl RangeBounds<&V>> { |
| 295 | + self.segments.first().map(|(start, _)| { |
| 296 | + let end = { |
| 297 | + self.segments |
| 298 | + .last() |
| 299 | + .and_then(|(_, l)| l.as_ref()) |
| 300 | + .map(Bound::Excluded) |
| 301 | + .unwrap_or(Bound::Unbounded) |
| 302 | + }; |
| 303 | + (Bound::Included(start), end) |
| 304 | + }) |
| 305 | + } |
263 | 306 | }
|
264 | 307 |
|
265 | 308 | // REPORT ######################################################################
|
|
0 commit comments