Generalized range abstractions.
This crate provides three capability traits, alongside the concrete range types that implement them:
- [
RangeStart] describes a range with a defined inclusive lower bound; it is the shared base of the two extension traits. - [
RangeExt] describes a range bounded on both ends, exposing its upper bound in both the inclusive and the exclusive form. - [
PartialRangeExt] describes a range that may be unbounded above or empty, exposing its upper bound losslessly through [RangeEnd] along with clamping and intersection operations. - [
Range] is a concrete bounded range whose end is either inclusive or exclusive, as recorded by [RangeEnd]. - [
PartialRange] is a concrete possibly-unbounded range that also implements [Iterator].
Each trait is implemented for the standard library range types, for
shared and mutable references, and for the concrete types above, wherever
the type's shape supports it. [RangeStart] and [PartialRangeExt] are
also implemented for [Option], with [None] as the empty range, so a
possibly-absent range remains usable as a range. The traits' method names
are disjoint, so all three can share scope.
Operations interpret Idx as a discrete domain in which x + one is the
successor of x. A bound is converted between its inclusive and
exclusive forms only where the converted bound is provably representable:
clamping compares bounds through [RangeEnd] or against window ends that
are themselves representable, so an inclusive end at the maximum index
value is handled faithfully, without saturation or widening.
Examples
use ;
// Clamp a slice request to a buffer's length.
let buffer = ;
let requested = 4usize..;
assert_eq!;
assert_eq!;
// Clamping requires only minimal trait bounds on the index type.
assert_eq!;
// Iteration eventually leaves every range exhausted.
let mut range = from;
assert_eq!;
assert_eq!;