pub struct Ranges<V> { /* private fields */ }
Expand description
Ranges represents multiple intervals of a continuous range of monotone increasing values.
Internally, Ranges
are an ordered list of segments, where segment is a bounds pair.
Invariants:
- The segments are sorted, from lowest to highest (through
Ord
). - Each segment contains at least one version (start < end).
- There is at least one version between two segments.
These ensure that equivalent instances have an identical representation, which is important
for Eq
and Hash
. Note that this representation cannot strictly guaranty equality of
Ranges
with equality of its representation without also knowing the nature of the underlying
versions. In particular, if the version space is discrete, different representations, using
different types of bounds (exclusive/inclusive) may correspond to the same set of existing
versions. It is a tradeoff we acknowledge, but which makes representations of continuous version
sets more accessible, to better handle features like pre-releases and other types of version
modifiers. For example, [(Included(3u32), Excluded(7u32))]
and
[(Included(3u32), Included(6u32))]
refer to the same version set, since there is no version
between 6 and 7, which this crate doesn’t know about.
Implementations§
Source§impl<V> Ranges<V>
impl<V> Ranges<V>
Sourcepub fn higher_than(v: impl Into<V>) -> Self
pub fn higher_than(v: impl Into<V>) -> Self
Set of all versions higher or equal to some version
Sourcepub fn strictly_higher_than(v: impl Into<V>) -> Self
pub fn strictly_higher_than(v: impl Into<V>) -> Self
Set of all versions higher to some version
Sourcepub fn strictly_lower_than(v: impl Into<V>) -> Self
pub fn strictly_lower_than(v: impl Into<V>) -> Self
Set of all versions lower to some version
Sourcepub fn lower_than(v: impl Into<V>) -> Self
pub fn lower_than(v: impl Into<V>) -> Self
Set of all versions lower or equal to some version
Source§impl<V: Clone> Ranges<V>
impl<V: Clone> Ranges<V>
Sourcepub fn complement(&self) -> Self
pub fn complement(&self) -> Self
Returns the complement, which contains everything not included in self
.
Source§impl<V: Ord> Ranges<V>
impl<V: Ord> Ranges<V>
Sourcepub fn as_singleton(&self) -> Option<&V>
pub fn as_singleton(&self) -> Option<&V>
If self contains exactly a single version, return it, otherwise, return None.
Sourcepub fn bounding_range(&self) -> Option<(Bound<&V>, Bound<&V>)>
pub fn bounding_range(&self) -> Option<(Bound<&V>, Bound<&V>)>
Convert to something that can be used with BTreeMap::range. All versions contained in self, will be in the output, but there may be versions in the output that are not contained in self. Returns None if the range is empty.
Sourcepub fn contains_many<'s, I, BV>(
&'s self,
versions: I,
) -> impl Iterator<Item = bool> + 's
pub fn contains_many<'s, I, BV>( &'s self, versions: I, ) -> impl Iterator<Item = bool> + 's
Returns true if self contains the specified values.
The versions
iterator must be sorted.
Functionally equivalent to versions.map(|v| self.contains(v))
.
Except it runs in O(size_of_range + len_of_versions)
not O(size_of_range * len_of_versions)
Sourcepub fn from_range_bounds<R, IV>(bounds: R) -> Self
pub fn from_range_bounds<R, IV>(bounds: R) -> Self
Construct a simple range from anything that impls RangeBounds like v1..v2
.
Source§impl<V: Ord + Clone> Ranges<V>
impl<V: Ord + Clone> Ranges<V>
Sourcepub fn intersection(&self, other: &Self) -> Self
pub fn intersection(&self, other: &Self) -> Self
Computes the intersection of two sets of versions.
Sourcepub fn is_disjoint(&self, other: &Self) -> bool
pub fn is_disjoint(&self, other: &Self) -> bool
Return true if there can be no V
so that V
is contained in both self
and other
.
Note that we don’t know that set of all existing V
s here, so we only check if the segments
are disjoint, not if no version is contained in both.
Sourcepub fn subset_of(&self, other: &Self) -> bool
pub fn subset_of(&self, other: &Self) -> bool
Return true if any V
that is contained in self
is also contained in other
.
Note that we don’t know that set of all existing V
s here, so we only check if all
segments self
are contained in a segment of other
.
Sourcepub fn simplify<'s, I, BV>(&self, versions: I) -> Self
pub fn simplify<'s, I, BV>(&self, versions: I) -> Self
Returns a simpler representation that contains the same versions.
For every one of the Versions provided in versions the existing range and the simplified range will agree on whether it is contained. The simplified version may include or exclude versions that are not in versions as the implementation wishes.
If none of the versions are contained in the original than the range will be returned unmodified.
If the range includes a single version, it will be returned unmodified.
If all the versions are contained in the original than the range will be simplified to full
.
If the given versions are not sorted the correctness of this function is not guaranteed.
Trait Implementations§
Source§impl<V: Ord> FromIterator<(Bound<V>, Bound<V>)> for Ranges<V>
impl<V: Ord> FromIterator<(Bound<V>, Bound<V>)> for Ranges<V>
Source§fn from_iter<T: IntoIterator<Item = (Bound<V>, Bound<V>)>>(iter: T) -> Self
fn from_iter<T: IntoIterator<Item = (Bound<V>, Bound<V>)>>(iter: T) -> Self
Constructor from arbitrary, unsorted and potentially overlapping ranges.
This is equivalent, but faster, to computing the Ranges::union
of the
Ranges::from_range_bounds
of each segment.
Source§impl<V> IntoIterator for Ranges<V>
impl<V> IntoIterator for Ranges<V>
Source§impl<V: Ord> Ord for Ranges<V>
impl<V: Ord> Ord for Ranges<V>
Source§impl<V: PartialOrd> PartialOrd for Ranges<V>
impl<V: PartialOrd> PartialOrd for Ranges<V>
Source§fn partial_cmp(&self, other: &Self) -> Option<Ordering>
fn partial_cmp(&self, other: &Self) -> Option<Ordering>
A simple ordering scheme where we zip the segments and compare all bounds in order. If all bounds are equal, the longer range is considered greater. (And if all zipped bounds are equal and we have the same number of segments, the ranges are equal).