1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
//! 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 ps_range::{PartialRange, PartialRangeExt, RangeExt};
//!
//! // Clamp a slice request to a buffer's length.
//! let buffer = [0u8; 10];
//! let requested = 4usize..;
//!
//! assert_eq!(requested.clamp_right_exclusive(buffer.len()), 4..10);
//! assert_eq!(buffer[requested.clamp_right_exclusive(buffer.len())].len(), 6);
//!
//! // Clamping requires only minimal trait bounds on the index type.
//! assert_eq!((..8).clamp_right(6usize), 0..6);
//!
//! // Iteration eventually leaves every range exhausted.
//! let mut range = PartialRange::from(254u8..);
//!
//! assert_eq!(range.by_ref().collect::<Vec<_>>(), vec![254, 255]);
//! assert_eq!(range, PartialRange::Exhausted);
//! ```
pub use PartialRange;
pub use PartialRangeExt;
pub use ;
pub use RangeExt;
pub use RangeStart;