fixed all doctests in map.rs and deleted set.rs since I'm gonna re-make it just pointing to map.rs
This commit is contained in:
+7
-7
@@ -196,13 +196,13 @@ mod tests {
|
||||
assert!(BoundOrd::StartExcluded(2) < BoundOrd::EndUnbounded);
|
||||
|
||||
//StartUnbounded
|
||||
assert!(BoundOrd::StartUnbounded::<u8> == BoundOrd::StartUnbounded);
|
||||
assert!(BoundOrd::StartUnbounded::<u8> <= BoundOrd::StartUnbounded);
|
||||
assert!(BoundOrd::StartUnbounded::<u8> >= BoundOrd::StartUnbounded);
|
||||
assert!(BoundOrd::StartUnbounded::<i8> == BoundOrd::StartUnbounded);
|
||||
assert!(BoundOrd::StartUnbounded::<i8> <= BoundOrd::StartUnbounded);
|
||||
assert!(BoundOrd::StartUnbounded::<i8> >= BoundOrd::StartUnbounded);
|
||||
|
||||
assert!(BoundOrd::StartUnbounded < BoundOrd::EndExcluded(2));
|
||||
|
||||
assert!(BoundOrd::StartUnbounded::<u8> < BoundOrd::EndUnbounded);
|
||||
assert!(BoundOrd::StartUnbounded::<i8> < BoundOrd::EndUnbounded);
|
||||
|
||||
//EndExcluded
|
||||
assert!(BoundOrd::EndExcluded(2) == BoundOrd::EndExcluded(2));
|
||||
@@ -212,8 +212,8 @@ mod tests {
|
||||
assert!(BoundOrd::EndExcluded(2) > BoundOrd::EndExcluded(0));
|
||||
|
||||
//EndUnbounded
|
||||
assert!(BoundOrd::EndUnbounded::<u8> == BoundOrd::EndUnbounded);
|
||||
assert!(BoundOrd::EndUnbounded::<u8> <= BoundOrd::EndUnbounded);
|
||||
assert!(BoundOrd::EndUnbounded::<u8> >= BoundOrd::EndUnbounded);
|
||||
assert!(BoundOrd::EndUnbounded::<i8> == BoundOrd::EndUnbounded);
|
||||
assert!(BoundOrd::EndUnbounded::<i8> <= BoundOrd::EndUnbounded);
|
||||
assert!(BoundOrd::EndUnbounded::<i8> >= BoundOrd::EndUnbounded);
|
||||
}
|
||||
}
|
||||
|
||||
+11
-9
@@ -29,13 +29,14 @@ along with range_bounds_map. If not, see <https://www.gnu.org/licenses/>.
|
||||
//!
|
||||
//! ```rust
|
||||
//! use range_bounds_map::RangeBoundsMap;
|
||||
//! use range_bounds_map::test_ranges::ie;
|
||||
//!
|
||||
//! let mut map = RangeBoundsMap::new();
|
||||
//!
|
||||
//! map.insert_strict(0..5, true);
|
||||
//! map.insert_strict(5..10, false);
|
||||
//! map.insert_strict(ie(0, 5), true);
|
||||
//! map.insert_strict(ie(5, 10), false);
|
||||
//!
|
||||
//! assert_eq!(map.overlaps(-2..12), true);
|
||||
//! assert_eq!(map.overlaps(ie(-2, 12)), true);
|
||||
//! assert_eq!(map.contains_point(20), false);
|
||||
//! assert_eq!(map.contains_point(5), true);
|
||||
//! ```
|
||||
@@ -46,18 +47,19 @@ along with range_bounds_map. If not, see <https://www.gnu.org/licenses/>.
|
||||
//! use std::ops::{Bound, RangeBounds};
|
||||
//!
|
||||
//! use range_bounds_map::RangeBoundsMap;
|
||||
//! use range_bounds_map::test_ranges::ie;
|
||||
//!
|
||||
//! #[derive(Debug, Copy, Clone)]
|
||||
//! enum Reservation {
|
||||
//! // Start, End (Inclusive-Inclusive)
|
||||
//! Finite(u8, u8),
|
||||
//! Finite(i8, i8),
|
||||
//! // Start (Exclusive)
|
||||
//! Infinite(u8),
|
||||
//! Infinite(i8),
|
||||
//! }
|
||||
//!
|
||||
//! // First, we need to implement RangeBounds
|
||||
//! impl RangeBounds<u8> for Reservation {
|
||||
//! fn start_bound(&self) -> Bound<&u8> {
|
||||
//! impl RangeBounds<i8> for Reservation {
|
||||
//! fn start_bound(&self) -> Bound<&i8> {
|
||||
//! match self {
|
||||
//! Reservation::Finite(start, _) => {
|
||||
//! Bound::Included(start)
|
||||
@@ -67,7 +69,7 @@ along with range_bounds_map. If not, see <https://www.gnu.org/licenses/>.
|
||||
//! }
|
||||
//! }
|
||||
//! }
|
||||
//! fn end_bound(&self) -> Bound<&u8> {
|
||||
//! fn end_bound(&self) -> Bound<&i8> {
|
||||
//! match self {
|
||||
//! Reservation::Finite(_, end) => Bound::Included(end),
|
||||
//! Reservation::Infinite(_) => Bound::Unbounded,
|
||||
@@ -82,7 +84,7 @@ along with range_bounds_map. If not, see <https://www.gnu.org/licenses/>.
|
||||
//! ])
|
||||
//! .unwrap();
|
||||
//!
|
||||
//! for (reservation, name) in reservation_map.overlapping(16..17)
|
||||
//! for (reservation, name) in reservation_map.overlapping(ie(16, 17))
|
||||
//! {
|
||||
//! println!(
|
||||
//! "{name} has reserved {reservation:?} inside the range 16..17"
|
||||
|
||||
+70
-57
@@ -109,7 +109,7 @@ use crate::TryFromBounds;
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// // Now we can make a [`RangeBoundsMap`] of [`ExEx`]s to `u8`
|
||||
/// // Now we can make a [`RangeBoundsMap`] of [`ExEx`]s to `i8`
|
||||
/// let mut map = RangeBoundsMap::new();
|
||||
///
|
||||
/// map.insert_strict(ExEx::new(0.0, 5.0), 8).unwrap();
|
||||
@@ -118,7 +118,10 @@ use crate::TryFromBounds;
|
||||
/// assert_eq!(map.contains_point(NotNan::new(5.0).unwrap()), false);
|
||||
///
|
||||
/// assert_eq!(map.get_at_point(NotNan::new(9.0).unwrap()), None);
|
||||
/// assert_eq!(map.get_at_point(NotNan::new(7.0).unwrap()), Some(32));
|
||||
/// assert_eq!(
|
||||
/// map.get_at_point(NotNan::new(7.0).unwrap()),
|
||||
/// Some(&32)
|
||||
/// );
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// map.get_entry_at_point(NotNan::new(2.0).unwrap()),
|
||||
@@ -161,11 +164,11 @@ pub struct OverlapError;
|
||||
/// return Err(TryFromBoundsError).
|
||||
///
|
||||
/// ```
|
||||
/// use range_bounds_map::test_ranges::{ie, ii};
|
||||
/// use range_bounds_map::test_ranges::{ii, ran};
|
||||
/// use range_bounds_map::{RangeBoundsMap, TryFromBoundsError};
|
||||
///
|
||||
/// let mut map =
|
||||
/// RangeBoundsMap::from_slice_strict([(ie(2, 8), true)])
|
||||
/// RangeBoundsMap::from_slice_strict([(ran(2, 8), true)])
|
||||
/// .unwrap();
|
||||
///
|
||||
/// assert!(map.cut(ii(4, 6)).is_err());
|
||||
@@ -203,12 +206,12 @@ pub struct OverlapError;
|
||||
///
|
||||
/// #[derive(Debug, Copy, Clone, PartialEq)]
|
||||
/// enum MultiBounds {
|
||||
/// Inclusive(u8, u8),
|
||||
/// Exclusive(u8, u8),
|
||||
/// Inclusive(i8, i8),
|
||||
/// Exclusive(i8, i8),
|
||||
/// }
|
||||
///
|
||||
/// impl RangeBounds<u8> for MultiBounds {
|
||||
/// fn start_bound(&self) -> Bound<&u8> {
|
||||
/// impl RangeBounds<i8> for MultiBounds {
|
||||
/// fn start_bound(&self) -> Bound<&i8> {
|
||||
/// match self {
|
||||
/// MultiBounds::Inclusive(start, _) => {
|
||||
/// Bound::Included(start)
|
||||
@@ -218,7 +221,7 @@ pub struct OverlapError;
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// fn end_bound(&self) -> Bound<&u8> {
|
||||
/// fn end_bound(&self) -> Bound<&i8> {
|
||||
/// match self {
|
||||
/// MultiBounds::Inclusive(_, end) => {
|
||||
/// Bound::Included(end)
|
||||
@@ -230,10 +233,10 @@ pub struct OverlapError;
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// impl TryFromBounds<u8> for MultiBounds {
|
||||
/// impl TryFromBounds<i8> for MultiBounds {
|
||||
/// fn try_from_bounds(
|
||||
/// start_bound: Bound<u8>,
|
||||
/// end_bound: Bound<u8>,
|
||||
/// start_bound: Bound<i8>,
|
||||
/// end_bound: Bound<i8>,
|
||||
/// ) -> Result<Self, TryFromBoundsError> {
|
||||
/// match (start_bound, end_bound) {
|
||||
/// (Bound::Included(start), Bound::Included(end)) => {
|
||||
@@ -288,7 +291,7 @@ where
|
||||
/// use range_bounds_map::test_ranges::TestBounds;
|
||||
/// use range_bounds_map::RangeBoundsMap;
|
||||
///
|
||||
/// let map: RangeBoundsMap<u8, TestBounds, bool> =
|
||||
/// let map: RangeBoundsMap<i8, TestBounds, bool> =
|
||||
/// RangeBoundsMap::new();
|
||||
/// ```
|
||||
pub fn new() -> Self {
|
||||
@@ -402,6 +405,10 @@ where
|
||||
where
|
||||
Q: NiceRange<I>,
|
||||
{
|
||||
if !is_valid_range(range) {
|
||||
panic!("Invalid RangeBounds!");
|
||||
}
|
||||
|
||||
let lower_comp = overlapping_start_comp(range.start());
|
||||
let upper_comp = overlapping_end_comp(range.end());
|
||||
|
||||
@@ -524,7 +531,7 @@ where
|
||||
///
|
||||
/// assert_eq!(iter.next(), Some((&ie(1, 4), &false)));
|
||||
/// assert_eq!(iter.next(), Some((&ie(4, 8), &true)));
|
||||
/// assert_eq!(iter.next(), Some((&ie(8, 0), &false)));
|
||||
/// assert_eq!(iter.next(), Some((&ie(8, 100), &false)));
|
||||
/// assert_eq!(iter.next(), None);
|
||||
/// ```
|
||||
pub fn iter(&self) -> impl DoubleEndedIterator<Item = (&K, &V)> {
|
||||
@@ -606,24 +613,24 @@ where
|
||||
/// ```
|
||||
/// use std::ops::Bound;
|
||||
///
|
||||
/// use range_bounds_map::test_ranges::{ie, ii};
|
||||
/// use range_bounds_map::test_ranges::{ie, ii, ran};
|
||||
/// use range_bounds_map::{RangeBoundsMap, TryFromBoundsError};
|
||||
///
|
||||
/// let mut base = RangeBoundsMap::from_slice_strict([
|
||||
/// (ie(1, 4), false),
|
||||
/// (ie(4, 8), true),
|
||||
/// (ie(8, 100), false),
|
||||
/// (ran(1, 4), false),
|
||||
/// (ran(4, 8), true),
|
||||
/// (ran(8, 100), false),
|
||||
/// ])
|
||||
/// .unwrap();
|
||||
///
|
||||
/// let after_cut = RangeBoundsMap::from_slice_strict([
|
||||
/// (ie(1, 2), false),
|
||||
/// (ie(40, 100), false),
|
||||
/// (ran(1, 2), false),
|
||||
/// (ran(40, 100), false),
|
||||
/// ])
|
||||
/// .unwrap();
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// base.cut(ie(2, 0)).unwrap().collect::<Vec<_>>(),
|
||||
/// base.cut(ie(2, 40)).unwrap().collect::<Vec<_>>(),
|
||||
/// [
|
||||
/// ((Bound::Included(2), Bound::Excluded(4)), false),
|
||||
/// ((Bound::Included(4), Bound::Excluded(8)), true),
|
||||
@@ -797,7 +804,7 @@ where
|
||||
/// ```
|
||||
/// use std::ops::Bound;
|
||||
///
|
||||
/// use range_bounds_map::test_ranges::ie;
|
||||
/// use range_bounds_map::test_ranges::{ie, iu};
|
||||
/// use range_bounds_map::RangeBoundsMap;
|
||||
///
|
||||
/// let map = RangeBoundsMap::from_slice_strict([
|
||||
@@ -807,7 +814,7 @@ where
|
||||
/// ])
|
||||
/// .unwrap();
|
||||
///
|
||||
/// let mut gaps = map.gaps(2..);
|
||||
/// let mut gaps = map.gaps(iu(2));
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// gaps.collect::<Vec<_>>(),
|
||||
@@ -894,7 +901,7 @@ where
|
||||
///
|
||||
/// assert_eq!(map.contains_range_bounds(ie(1, 3)), true);
|
||||
/// assert_eq!(map.contains_range_bounds(ie(2, 6)), false);
|
||||
/// assert_eq!(map.contains_range_bounds(ie(6, 0)), true);
|
||||
/// assert_eq!(map.contains_range_bounds(ie(6, 100)), true);
|
||||
/// ```
|
||||
pub fn contains_range_bounds<Q>(&self, range_bounds: Q) -> bool
|
||||
where
|
||||
@@ -1038,12 +1045,12 @@ where
|
||||
/// // Neither Touching or Overlapping
|
||||
/// assert_eq!(
|
||||
/// map.insert_merge_touching(ie(10, 16), false),
|
||||
/// Ok(ie(0, 6))
|
||||
/// Ok(ie(10, 16))
|
||||
/// );
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// map.iter().collect::<Vec<_>>(),
|
||||
/// [(&ie(1, 6), &true), (&ie(10, 6), &false)]
|
||||
/// [(&ie(1, 6), &true), (&ie(10, 16), &false)]
|
||||
/// );
|
||||
/// ```
|
||||
pub fn insert_merge_touching(
|
||||
@@ -1128,7 +1135,7 @@ where
|
||||
/// // Neither Touching or Overlapping
|
||||
/// assert_eq!(
|
||||
/// map.insert_merge_overlapping(ie(10, 16), false),
|
||||
/// Ok(ie(0, 6))
|
||||
/// Ok(ie(10, 16))
|
||||
/// );
|
||||
///
|
||||
/// assert_eq!(
|
||||
@@ -1136,7 +1143,7 @@ where
|
||||
/// [
|
||||
/// (&ie(-4, 1), &true),
|
||||
/// (&ie(1, 8), &true),
|
||||
/// (&ie(0, 6), &false)
|
||||
/// (&ie(10, 16), &false)
|
||||
/// ]
|
||||
/// );
|
||||
/// ```
|
||||
@@ -1144,7 +1151,10 @@ where
|
||||
&mut self,
|
||||
range: K,
|
||||
value: V,
|
||||
) -> Result<K, TryFromBoundsError> where K: TryFromBounds<I>{
|
||||
) -> Result<K, TryFromBoundsError>
|
||||
where
|
||||
K: TryFromBounds<I>,
|
||||
{
|
||||
self.insert_merge_with_comps(
|
||||
range,
|
||||
value,
|
||||
@@ -1210,19 +1220,22 @@ where
|
||||
/// // Neither Touching or Overlapping
|
||||
/// assert_eq!(
|
||||
/// map.insert_merge_touching_or_overlapping(ie(10, 16), false),
|
||||
/// Ok(ie(0, 6))
|
||||
/// Ok(ie(10, 16))
|
||||
/// );
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// map.iter().collect::<Vec<_>>(),
|
||||
/// [(&ie(-4, 8), &true), (&ie(0, 6), &false)]
|
||||
/// [(&ie(-4, 8), &true), (&ie(10, 16), &false)]
|
||||
/// );
|
||||
/// ```
|
||||
pub fn insert_merge_touching_or_overlapping(
|
||||
&mut self,
|
||||
range: K,
|
||||
value: V,
|
||||
) -> Result<K, TryFromBoundsError> where K: TryFromBounds<I>{
|
||||
) -> Result<K, TryFromBoundsError>
|
||||
where
|
||||
K: TryFromBounds<I>,
|
||||
{
|
||||
self.insert_merge_with_comps(
|
||||
range,
|
||||
value,
|
||||
@@ -1300,7 +1313,7 @@ where
|
||||
value: V,
|
||||
) -> Result<(), TryFromBoundsError>
|
||||
where
|
||||
K: TryFromBounds<I>,
|
||||
K: TryFromBounds<I>,
|
||||
V: Clone,
|
||||
{
|
||||
let _ = self.cut(range)?;
|
||||
@@ -1347,7 +1360,7 @@ where
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// map.last_entry(),
|
||||
/// Some((&ie(8, 0), &false))
|
||||
/// Some((&ie(8, 100), &false))
|
||||
/// );
|
||||
pub fn last_entry(&self) -> Option<(&K, &V)> {
|
||||
self.inner.last_key_value()
|
||||
@@ -1479,12 +1492,12 @@ mod tests {
|
||||
|
||||
//only every other number to allow mathematical_overlapping_definition
|
||||
//to test between bounds in finite using smaller intervalled finite
|
||||
pub(crate) const NUMBERS: &'static [u8] = &[2, 4, 6, 8, 10];
|
||||
pub(crate) const NUMBERS: &'static [i8] = &[2, 4, 6, 8, 10];
|
||||
//go a bit around on either side to compensate for Unbounded
|
||||
pub(crate) const NUMBERS_DOMAIN: &'static [u8] =
|
||||
pub(crate) const NUMBERS_DOMAIN: &'static [i8] =
|
||||
&[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
|
||||
|
||||
fn basic() -> RangeBoundsMap<u8, TestBounds, bool> {
|
||||
fn basic() -> RangeBoundsMap<i8, TestBounds, bool> {
|
||||
RangeBoundsMap::from_slice_strict([
|
||||
(ui(4), false),
|
||||
(ee(5, 7), true),
|
||||
@@ -1494,7 +1507,7 @@ mod tests {
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn special() -> RangeBoundsMap<u8, MultiBounds, bool> {
|
||||
fn special() -> RangeBoundsMap<i8, MultiBounds, bool> {
|
||||
RangeBoundsMap::from_slice_strict([
|
||||
(mii(4, 6), false),
|
||||
(mee(7, 8), true),
|
||||
@@ -1505,35 +1518,35 @@ mod tests {
|
||||
|
||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||
enum MultiBounds {
|
||||
Inclusive(u8, u8),
|
||||
Exclusive(u8, u8),
|
||||
Inclusive(i8, i8),
|
||||
Exclusive(i8, i8),
|
||||
}
|
||||
|
||||
fn mii(start: u8, end: u8) -> MultiBounds {
|
||||
fn mii(start: i8, end: i8) -> MultiBounds {
|
||||
MultiBounds::Inclusive(start, end)
|
||||
}
|
||||
fn mee(start: u8, end: u8) -> MultiBounds {
|
||||
fn mee(start: i8, end: i8) -> MultiBounds {
|
||||
MultiBounds::Exclusive(start, end)
|
||||
}
|
||||
|
||||
impl RangeBounds<u8> for MultiBounds {
|
||||
fn start_bound(&self) -> Bound<&u8> {
|
||||
impl RangeBounds<i8> for MultiBounds {
|
||||
fn start_bound(&self) -> Bound<&i8> {
|
||||
match self {
|
||||
MultiBounds::Inclusive(start, _) => Bound::Included(start),
|
||||
MultiBounds::Exclusive(start, _) => Bound::Excluded(start),
|
||||
}
|
||||
}
|
||||
fn end_bound(&self) -> Bound<&u8> {
|
||||
fn end_bound(&self) -> Bound<&i8> {
|
||||
match self {
|
||||
MultiBounds::Inclusive(_, end) => Bound::Included(end),
|
||||
MultiBounds::Exclusive(_, end) => Bound::Excluded(end),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl TryFromBounds<u8> for MultiBounds {
|
||||
impl TryFromBounds<i8> for MultiBounds {
|
||||
fn try_from_bounds(
|
||||
start_bound: Bound<u8>,
|
||||
end_bound: Bound<u8>,
|
||||
start_bound: Bound<i8>,
|
||||
end_bound: Bound<i8>,
|
||||
) -> Result<Self, TryFromBoundsError> {
|
||||
match (start_bound, end_bound) {
|
||||
(Bound::Included(start), Bound::Included(end)) => {
|
||||
@@ -1593,7 +1606,7 @@ mod tests {
|
||||
);
|
||||
}
|
||||
fn assert_insert_strict<const N: usize>(
|
||||
mut before: RangeBoundsMap<u8, TestBounds, bool>,
|
||||
mut before: RangeBoundsMap<i8, TestBounds, bool>,
|
||||
to_insert: (TestBounds, bool),
|
||||
result: Result<(), OverlapError>,
|
||||
after: Option<[(TestBounds, bool); N]>,
|
||||
@@ -1617,7 +1630,7 @@ mod tests {
|
||||
for overlap_range in all_valid_test_bounds() {
|
||||
//you can't overlap nothing
|
||||
assert!(
|
||||
RangeBoundsMap::<u8, TestBounds, ()>::new()
|
||||
RangeBoundsMap::<i8, TestBounds, ()>::new()
|
||||
.overlapping(overlap_range)
|
||||
.next()
|
||||
.is_none()
|
||||
@@ -1721,7 +1734,7 @@ mod tests {
|
||||
);
|
||||
}
|
||||
fn assert_remove_overlapping<const N: usize, const Y: usize>(
|
||||
mut before: RangeBoundsMap<u8, TestBounds, bool>,
|
||||
mut before: RangeBoundsMap<i8, TestBounds, bool>,
|
||||
to_remove: TestBounds,
|
||||
result: [(TestBounds, bool); N],
|
||||
after: Option<[(TestBounds, bool); Y]>,
|
||||
@@ -1858,7 +1871,7 @@ mod tests {
|
||||
assert_gaps(basic(), ii(8, 8), [ii(8, 8)]);
|
||||
}
|
||||
fn assert_gaps<const N: usize>(
|
||||
map: RangeBoundsMap<u8, TestBounds, bool>,
|
||||
map: RangeBoundsMap<i8, TestBounds, bool>,
|
||||
outer_range_bounds: TestBounds,
|
||||
result: [TestBounds; N],
|
||||
) {
|
||||
@@ -2313,7 +2326,7 @@ mod tests {
|
||||
}
|
||||
}
|
||||
}
|
||||
fn con(x: Option<(Bound<u8>, Bound<u8>)>, point: &u8) -> bool {
|
||||
fn con(x: Option<(Bound<i8>, Bound<i8>)>, point: &i8) -> bool {
|
||||
match x {
|
||||
Some(y) => y.contains(point),
|
||||
None => false,
|
||||
@@ -2321,7 +2334,7 @@ mod tests {
|
||||
}
|
||||
#[test]
|
||||
fn cut_range_bounds_should_return_valid_ranges() {
|
||||
let result: CutResult<u8> = cut_range(ie(3, 8), ie(5, 8));
|
||||
let result: CutResult<i8> = cut_range(ie(3, 8), ie(5, 8));
|
||||
if let Some(x) = result.before_cut {
|
||||
assert!(is_valid_range(x));
|
||||
}
|
||||
@@ -2403,7 +2416,7 @@ mod tests {
|
||||
return output;
|
||||
}
|
||||
|
||||
fn all_finite_bounded_entries() -> Vec<(Bound<u8>, Bound<u8>)> {
|
||||
fn all_finite_bounded_entries() -> Vec<(Bound<i8>, Bound<i8>)> {
|
||||
let mut output = Vec::new();
|
||||
for i in NUMBERS {
|
||||
for j in NUMBERS {
|
||||
@@ -2422,7 +2435,7 @@ mod tests {
|
||||
return output;
|
||||
}
|
||||
|
||||
fn all_finite_bounded() -> Vec<Bound<u8>> {
|
||||
fn all_finite_bounded() -> Vec<Bound<i8>> {
|
||||
let mut output = Vec::new();
|
||||
for i in NUMBERS {
|
||||
for j in 0..=1 {
|
||||
@@ -2432,7 +2445,7 @@ mod tests {
|
||||
return output;
|
||||
}
|
||||
|
||||
fn finite_bound(x: u8, included: bool) -> Bound<u8> {
|
||||
fn finite_bound(x: i8, included: bool) -> Bound<i8> {
|
||||
match included {
|
||||
false => Bound::Included(x),
|
||||
true => Bound::Excluded(x),
|
||||
|
||||
@@ -1,846 +1,3 @@
|
||||
/*
|
||||
Copyright 2022 James Forster
|
||||
|
||||
This file is part of range_bounds_map.
|
||||
|
||||
range_bounds_map is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
range_bounds_map is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with range_bounds_map. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use std::fmt::{self, Debug};
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::{Bound, RangeBounds};
|
||||
|
||||
use labels::trivial;
|
||||
use serde::de::{SeqAccess, Visitor};
|
||||
use serde::ser::SerializeSeq;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
use crate::range_bounds_map::IntoIter as MapIntoIter;
|
||||
use crate::{
|
||||
OverlapError, OverlapOrTryFromBoundsError, RangeBoundsMap, TryFromBounds,
|
||||
TryFromBoundsError,
|
||||
};
|
||||
|
||||
/// An ordered set of non-overlapping [`RangeBounds`] based on [`RangeBoundsMap`].
|
||||
///
|
||||
/// `I` is the generic type parameter for the [`Ord`] type the `K`
|
||||
/// type is [`RangeBounds`] over.
|
||||
///
|
||||
/// `K` is the generic type parameter for the [`RangeBounds`]
|
||||
/// implementing type in the set.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use range_bounds_map::RangeBoundsSet;
|
||||
///
|
||||
/// // Make a new set
|
||||
/// let mut set =
|
||||
/// RangeBoundsSet::from_slice_strict([4..8, 8..18, 20..100])
|
||||
/// .unwrap();
|
||||
///
|
||||
/// if set.contains_point(&99) {
|
||||
/// println!("Set contains value at 99 :)");
|
||||
/// }
|
||||
///
|
||||
/// // Iterate over the entries in the set
|
||||
/// for range in set.iter() {
|
||||
/// println!("{range:?}");
|
||||
/// }
|
||||
/// ```
|
||||
/// Example using a custom [`RangeBounds`] type:
|
||||
/// ```
|
||||
/// use std::ops::{Bound, RangeBounds};
|
||||
///
|
||||
/// use ordered_float::NotNan;
|
||||
/// use range_bounds_map::RangeBoundsSet;
|
||||
///
|
||||
/// // An Exlusive-Exlusive range of [`f32`]s not provided by any
|
||||
/// // std::ops ranges
|
||||
/// // We use [`ordered_float::NotNan`]s as the inner type must be Ord
|
||||
/// // similar to a normal [`BTreeSet`]
|
||||
/// #[derive(Debug, PartialEq)]
|
||||
/// struct ExEx {
|
||||
/// start: NotNan<f32>,
|
||||
/// end: NotNan<f32>,
|
||||
/// }
|
||||
/// # impl ExEx {
|
||||
/// # fn new(start: f32, end: f32) -> ExEx {
|
||||
/// # ExEx {
|
||||
/// # start: NotNan::new(start).unwrap(),
|
||||
/// # end: NotNan::new(end).unwrap(),
|
||||
/// # }
|
||||
/// # }
|
||||
/// # }
|
||||
///
|
||||
/// // Implement RangeBounds<f32> on our new type
|
||||
/// impl RangeBounds<NotNan<f32>> for ExEx {
|
||||
/// fn start_bound(&self) -> Bound<&NotNan<f32>> {
|
||||
/// Bound::Excluded(&self.start)
|
||||
/// }
|
||||
/// fn end_bound(&self) -> Bound<&NotNan<f32>> {
|
||||
/// Bound::Excluded(&self.end)
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// // Now we can make a [`RangeBoundsSet`] of [`ExEx`]s
|
||||
/// let mut set = RangeBoundsSet::new();
|
||||
///
|
||||
/// set.insert_strict(ExEx::new(0.0, 5.0)).unwrap();
|
||||
/// set.insert_strict(ExEx::new(5.0, 7.5)).unwrap();
|
||||
///
|
||||
/// assert_eq!(set.contains_point(&NotNan::new(5.0).unwrap()), false);
|
||||
///
|
||||
/// assert_eq!(set.get_at_point(&NotNan::new(9.0).unwrap()), None);
|
||||
/// assert_eq!(
|
||||
/// set.get_at_point(&NotNan::new(7.0).unwrap()),
|
||||
/// Some(&ExEx::new(5.0, 7.5))
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
/// [`RangeBounds`]: https://doc.rust-lang.org/std/ops/trait.RangeBounds.html
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct RangeBoundsSet<I, K>
|
||||
where
|
||||
I: Ord,
|
||||
{
|
||||
map: RangeBoundsMap<I, K, ()>,
|
||||
}
|
||||
|
||||
impl<I, K> RangeBoundsSet<I, K>
|
||||
where
|
||||
K: RangeBounds<I>,
|
||||
I: Ord + Clone,
|
||||
{
|
||||
/// Makes a new, empty `RangeBoundsSet`.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use std::ops::Range;
|
||||
///
|
||||
/// use range_bounds_map::RangeBoundsSet;
|
||||
///
|
||||
/// let set: RangeBoundsSet<u8, Range<u8>> = RangeBoundsSet::new();
|
||||
/// ```
|
||||
#[trivial]
|
||||
pub fn new() -> Self {
|
||||
RangeBoundsSet {
|
||||
map: RangeBoundsMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the number of `RangeBounds` in the set.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use range_bounds_map::RangeBoundsSet;
|
||||
///
|
||||
/// let mut set = RangeBoundsSet::new();
|
||||
///
|
||||
/// assert_eq!(set.len(), 0);
|
||||
/// set.insert_strict(0..1).unwrap();
|
||||
/// assert_eq!(set.len(), 1);
|
||||
/// ```
|
||||
#[trivial]
|
||||
pub fn len(&self) -> usize {
|
||||
self.map.len()
|
||||
}
|
||||
|
||||
/// Returns `true` if the set contains no `RangeBounds`, and
|
||||
/// `false` if it does.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use range_bounds_map::RangeBoundsSet;
|
||||
///
|
||||
/// let mut set = RangeBoundsSet::new();
|
||||
///
|
||||
/// assert_eq!(set.is_empty(), true);
|
||||
/// set.insert_strict(0..1).unwrap();
|
||||
/// assert_eq!(set.is_empty(), false);
|
||||
/// ```
|
||||
#[trivial]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.map.is_empty()
|
||||
}
|
||||
|
||||
/// Returns `true` if the given `RangeBounds` overlaps any of the
|
||||
/// `RangeBounds` in the set, and `false` if not.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the given `range_bounds` is an invalid
|
||||
/// `RangeBounds`. See [`Invalid
|
||||
/// RangeBounds`](https://docs.rs/range_bounds_map/latest/range_bounds_map/index.html#Invalid-RangeBounds)
|
||||
/// for more details.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use range_bounds_map::RangeBoundsSet;
|
||||
///
|
||||
/// let mut set = RangeBoundsSet::new();
|
||||
///
|
||||
/// set.insert_strict(5..10);
|
||||
///
|
||||
/// assert_eq!(set.overlaps(&(1..=3)), false);
|
||||
/// assert_eq!(set.overlaps(&(4..5)), false);
|
||||
///
|
||||
/// assert_eq!(set.overlaps(&(4..=5)), true);
|
||||
/// assert_eq!(set.overlaps(&(4..6)), true);
|
||||
/// ```
|
||||
#[trivial]
|
||||
pub fn overlaps<Q>(&self, range_bounds: &Q) -> bool
|
||||
where
|
||||
Q: RangeBounds<I>,
|
||||
{
|
||||
self.map.overlaps(range_bounds)
|
||||
}
|
||||
|
||||
/// Returns an iterator over every `RangeBounds` in the set which
|
||||
/// overlap the given `RangeBounds` in ascending order.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the given `range_bounds` is an invalid
|
||||
/// `RangeBounds`. See [`Invalid
|
||||
/// RangeBounds`](https://docs.rs/range_bounds_map/latest/range_bounds_map/index.html#Invalid-RangeBounds)
|
||||
/// for more details.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use range_bounds_map::RangeBoundsSet;
|
||||
///
|
||||
/// let set = RangeBoundsSet::from_slice_strict([1..4, 4..8, 8..100])
|
||||
/// .unwrap();
|
||||
///
|
||||
/// let mut overlapping = set.overlapping(&(2..8));
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// overlapping.collect::<Vec<_>>(),
|
||||
/// [(&(1..4)), (&(4..8))]
|
||||
/// );
|
||||
/// ```
|
||||
#[trivial]
|
||||
pub fn overlapping<Q>(
|
||||
&self,
|
||||
range_bounds: &Q,
|
||||
) -> impl DoubleEndedIterator<Item = &K>
|
||||
where
|
||||
Q: RangeBounds<I>,
|
||||
{
|
||||
self.map.overlapping(range_bounds).map(|(key, _)| key)
|
||||
}
|
||||
|
||||
/// Returns a reference to the `RangeBounds` in the set that
|
||||
/// overlaps the given point, if any.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use range_bounds_map::RangeBoundsSet;
|
||||
///
|
||||
/// let set = RangeBoundsSet::from_slice_strict([1..4, 4..8, 8..100])
|
||||
/// .unwrap();
|
||||
///
|
||||
/// assert_eq!(set.get_at_point(&3), Some(&(1..4)));
|
||||
/// assert_eq!(set.get_at_point(&4), Some(&(4..8)));
|
||||
/// assert_eq!(set.get_at_point(&101), None);
|
||||
/// ```
|
||||
#[trivial]
|
||||
pub fn get_at_point(&self, point: &I) -> Option<&K> {
|
||||
self.map.get_entry_at_point(point).map(|(key, _)| key)
|
||||
}
|
||||
|
||||
/// Returns `true` if the set contains a `RangeBounds` that
|
||||
/// overlaps the given point, and `false` if not.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use range_bounds_map::RangeBoundsSet;
|
||||
///
|
||||
/// let set = RangeBoundsSet::from_slice_strict([1..4, 4..8, 8..100])
|
||||
/// .unwrap();
|
||||
///
|
||||
/// assert_eq!(set.contains_point(&3), true);
|
||||
/// assert_eq!(set.contains_point(&4), true);
|
||||
/// assert_eq!(set.contains_point(&101), false);
|
||||
/// ```
|
||||
#[trivial]
|
||||
pub fn contains_point(&self, point: &I) -> bool {
|
||||
self.map.contains_point(point)
|
||||
}
|
||||
|
||||
/// Returns an iterator over every `RangeBounds` in the set in
|
||||
/// ascending order.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use range_bounds_map::RangeBoundsSet;
|
||||
///
|
||||
/// let set = RangeBoundsSet::from_slice_strict([1..4, 4..8, 8..100])
|
||||
/// .unwrap();
|
||||
///
|
||||
/// let mut iter = set.iter();
|
||||
///
|
||||
/// assert_eq!(iter.next(), Some(&(1..4)));
|
||||
/// assert_eq!(iter.next(), Some(&(4..8)));
|
||||
/// assert_eq!(iter.next(), Some(&(8..100)));
|
||||
/// assert_eq!(iter.next(), None);
|
||||
/// ```
|
||||
#[trivial]
|
||||
pub fn iter(&self) -> impl DoubleEndedIterator<Item = &K> {
|
||||
self.map.iter().map(|(key, _)| key)
|
||||
}
|
||||
|
||||
/// Removes every `RangeBounds` in the set which overlaps the
|
||||
/// given `RangeBounds` and returns them in an iterator.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the given `range_bounds` is an invalid
|
||||
/// `RangeBounds`. See [`Invalid
|
||||
/// RangeBounds`](https://docs.rs/range_bounds_map/latest/range_bounds_map/index.html#Invalid-RangeBounds)
|
||||
/// for more details.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use range_bounds_map::RangeBoundsSet;
|
||||
///
|
||||
/// let mut set =
|
||||
/// RangeBoundsSet::from_slice_strict([1..4, 4..8, 8..100])
|
||||
/// .unwrap();
|
||||
///
|
||||
/// let mut removed = set.remove_overlapping(&(2..8));
|
||||
///
|
||||
/// assert_eq!(removed.collect::<Vec<_>>(), [1..4, 4..8]);
|
||||
///
|
||||
/// assert_eq!(set.iter().collect::<Vec<_>>(), [&(8..100)]);
|
||||
/// ```
|
||||
#[trivial]
|
||||
pub fn remove_overlapping<Q>(
|
||||
&mut self,
|
||||
range_bounds: &Q,
|
||||
) -> impl DoubleEndedIterator<Item = K>
|
||||
where
|
||||
Q: RangeBounds<I>,
|
||||
{
|
||||
self.map
|
||||
.remove_overlapping(range_bounds)
|
||||
.map(|(key, _)| key)
|
||||
}
|
||||
|
||||
/// Cuts a given `RangeBounds` out of the set and returns an
|
||||
/// iterator of the full or partial `RangeBounds` that were cut in
|
||||
/// as `(Bound, Bound)`.
|
||||
///
|
||||
/// If the remaining `RangeBounds` left in the map after the cut
|
||||
/// are not able be created with the [`TryFromBounds`] trait then
|
||||
/// a [`TryFromBoundsError`] will be returned.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the given `range_bounds` is an invalid
|
||||
/// `RangeBounds`. See [`Invalid
|
||||
/// RangeBounds`](https://docs.rs/range_bounds_map/latest/range_bounds_map/index.html#Invalid-RangeBounds)
|
||||
/// for more details.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use std::ops::Bound;
|
||||
///
|
||||
/// use range_bounds_map::{RangeBoundsSet, TryFromBoundsError};
|
||||
///
|
||||
/// let mut base =
|
||||
/// RangeBoundsSet::from_slice_strict([1..4, 4..8, 8..100])
|
||||
/// .unwrap();
|
||||
///
|
||||
/// let after_cut =
|
||||
/// RangeBoundsSet::from_slice_strict([1..2, 40..100]).unwrap();
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// base.cut(&(2..40)).unwrap().collect::<Vec<_>>(),
|
||||
/// [
|
||||
/// (Bound::Included(2), Bound::Excluded(4)),
|
||||
/// (Bound::Included(4), Bound::Excluded(8)),
|
||||
/// (Bound::Included(8), Bound::Excluded(40)),
|
||||
/// ]
|
||||
/// );
|
||||
/// assert_eq!(base, after_cut);
|
||||
/// assert!(base.cut(&(60..=80)).is_err());
|
||||
/// ```
|
||||
#[trivial]
|
||||
pub fn cut<Q>(
|
||||
&mut self,
|
||||
range_bounds: &Q,
|
||||
) -> Result<
|
||||
impl DoubleEndedIterator<Item = (Bound<I>, Bound<I>)>,
|
||||
TryFromBoundsError,
|
||||
>
|
||||
where
|
||||
Q: RangeBounds<I>,
|
||||
K: TryFromBounds<I>,
|
||||
{
|
||||
self.map.cut(range_bounds).map(|x| x.map(|(key, _)| key))
|
||||
}
|
||||
|
||||
/// Returns an iterator of `(Bound<&I>, Bound<&I>)` over all the
|
||||
/// maximally-sized gaps in the set that are also within the given
|
||||
/// `outer_range_bounds`.
|
||||
///
|
||||
/// To get all possible gaps call `gaps()` with an unbounded
|
||||
/// `RangeBounds` such as `&(..)` or `&(Bound::Unbounded,
|
||||
/// Bound::Unbounded)`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the given `outer_range_bounds` is an invalid
|
||||
/// `RangeBounds`. See [`Invalid
|
||||
/// RangeBounds`](https://docs.rs/range_bounds_map/latest/range_bounds_map/index.html#Invalid-RangeBounds)
|
||||
/// for more details.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use std::ops::Bound;
|
||||
///
|
||||
/// use range_bounds_map::RangeBoundsSet;
|
||||
///
|
||||
/// let set = RangeBoundsSet::from_slice_strict([1..3, 5..7, 9..100])
|
||||
/// .unwrap();
|
||||
///
|
||||
/// let mut gaps = set.gaps(&(2..));
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// gaps.collect::<Vec<_>>(),
|
||||
/// [
|
||||
/// (Bound::Included(&3), Bound::Excluded(&5)),
|
||||
/// (Bound::Included(&7), Bound::Excluded(&9)),
|
||||
/// (Bound::Included(&100), Bound::Unbounded)
|
||||
/// ]
|
||||
/// );
|
||||
/// ```
|
||||
#[trivial]
|
||||
pub fn gaps<'a, Q>(
|
||||
&'a self,
|
||||
outer_range_bounds: &'a Q,
|
||||
) -> impl Iterator<Item = (Bound<&I>, Bound<&I>)>
|
||||
where
|
||||
Q: RangeBounds<I>,
|
||||
{
|
||||
self.map.gaps(outer_range_bounds)
|
||||
}
|
||||
|
||||
/// Returns `true` if the set covers every point in the given
|
||||
/// `RangeBounds`, and `false` if it doesn't.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the given `range_bounds` is an invalid
|
||||
/// `RangeBounds`. See [`Invalid
|
||||
/// RangeBounds`](https://docs.rs/range_bounds_map/latest/range_bounds_map/index.html#Invalid-RangeBounds)
|
||||
/// for more details.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use range_bounds_map::RangeBoundsSet;
|
||||
///
|
||||
/// let set = RangeBoundsSet::from_slice_strict([1..3, 5..8, 8..100])
|
||||
/// .unwrap();
|
||||
///
|
||||
/// assert_eq!(set.contains_range_bounds(&(1..3)), true);
|
||||
/// assert_eq!(set.contains_range_bounds(&(2..6)), false);
|
||||
/// assert_eq!(set.contains_range_bounds(&(6..50)), true);
|
||||
/// ```
|
||||
#[trivial]
|
||||
pub fn contains_range_bounds<Q>(&self, range_bounds: &Q) -> bool
|
||||
where
|
||||
Q: RangeBounds<I>,
|
||||
{
|
||||
self.map.contains_range_bounds(range_bounds)
|
||||
}
|
||||
|
||||
/// Adds a new `RangeBounds` to the set without modifying other
|
||||
/// `RangeBounds` in the set.
|
||||
///
|
||||
/// If the given `RangeBounds` overlaps one or more `RangeBounds`
|
||||
/// already in the set, then an [`OverlapError`] is returned and
|
||||
/// the set is not updated.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the given `range_bounds` is an invalid
|
||||
/// `RangeBounds`. See [`Invalid
|
||||
/// RangeBounds`](https://docs.rs/range_bounds_map/latest/range_bounds_map/index.html#Invalid-RangeBounds)
|
||||
/// for more details.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use range_bounds_map::{OverlapError, RangeBoundsSet};
|
||||
///
|
||||
/// let mut set = RangeBoundsSet::new();
|
||||
///
|
||||
/// assert_eq!(set.insert_strict(5..10), Ok(()));
|
||||
/// assert_eq!(set.insert_strict(5..10), Err(OverlapError));
|
||||
/// assert_eq!(set.len(), 1);
|
||||
/// ```
|
||||
#[trivial]
|
||||
pub fn insert_strict(
|
||||
&mut self,
|
||||
range_bounds: K,
|
||||
) -> Result<(), OverlapError> {
|
||||
self.map.insert_strict(range_bounds, ())
|
||||
}
|
||||
|
||||
/// Adds a new `RangeBounds` to the set and merges into other
|
||||
/// `RangeBounds` in the set which touch it.
|
||||
///
|
||||
/// If successful then a reference to the newly inserted
|
||||
/// `RangeBounds` is returned.
|
||||
///
|
||||
/// If the given `RangeBounds` overlaps one or more `RangeBounds`
|
||||
/// already in the set, then an [`OverlapError`] is returned and
|
||||
/// the set is not updated.
|
||||
///
|
||||
/// If the merged `RangeBounds` cannot be created with the
|
||||
/// [`TryFromBounds`] trait then a [`TryFromBoundsError`] will be
|
||||
/// returned.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the given `range_bounds` is an invalid
|
||||
/// `RangeBounds`. See [`Invalid
|
||||
/// RangeBounds`](https://docs.rs/range_bounds_map/latest/range_bounds_map/index.html#Invalid-RangeBounds)
|
||||
/// for more details.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use range_bounds_map::{
|
||||
/// OverlapError, OverlapOrTryFromBoundsError, RangeBoundsSet,
|
||||
/// };
|
||||
///
|
||||
/// let mut set = RangeBoundsSet::from_slice_strict([1..4]).unwrap();
|
||||
///
|
||||
/// // Touching
|
||||
/// assert_eq!(set.insert_merge_touching(4..6), Ok(&(1..6)));
|
||||
///
|
||||
/// // Overlapping
|
||||
/// assert_eq!(
|
||||
/// set.insert_merge_touching(4..8),
|
||||
/// Err(OverlapOrTryFromBoundsError::Overlap(OverlapError)),
|
||||
/// );
|
||||
///
|
||||
/// // Neither Touching or Overlapping
|
||||
/// assert_eq!(set.insert_merge_touching(10..16), Ok(&(10..16)));
|
||||
///
|
||||
/// assert_eq!(set.iter().collect::<Vec<_>>(), [&(1..6), &(10..16)]);
|
||||
/// ```
|
||||
#[trivial]
|
||||
pub fn insert_merge_touching(
|
||||
&mut self,
|
||||
range_bounds: K,
|
||||
) -> Result<&K, OverlapOrTryFromBoundsError>
|
||||
where
|
||||
K: TryFromBounds<I>,
|
||||
{
|
||||
self.map.insert_merge_touching(range_bounds, ())
|
||||
}
|
||||
|
||||
/// Adds a new `RangeBounds` to the set and merges into other
|
||||
/// `RangeBounds` in the set which overlap it.
|
||||
///
|
||||
/// If successful then a reference to the newly inserted
|
||||
/// `RangeBounds` is returned.
|
||||
///
|
||||
/// If the merged `RangeBounds` cannot be created with the
|
||||
/// [`TryFromBounds`] trait then a [`TryFromBoundsError`] will be
|
||||
/// returned.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the given `range_bounds` is an invalid
|
||||
/// `RangeBounds`. See [`Invalid
|
||||
/// RangeBounds`](https://docs.rs/range_bounds_map/latest/range_bounds_map/index.html#Invalid-RangeBounds)
|
||||
/// for more details.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use range_bounds_map::RangeBoundsSet;
|
||||
///
|
||||
/// let mut set = RangeBoundsSet::from_slice_strict([1..4]).unwrap();
|
||||
///
|
||||
/// // Touching
|
||||
/// assert_eq!(set.insert_merge_overlapping(-4..1), Ok(&(-4..1)));
|
||||
///
|
||||
/// // Overlapping
|
||||
/// assert_eq!(set.insert_merge_overlapping(2..8), Ok(&(1..8)));
|
||||
///
|
||||
/// // Neither Touching or Overlapping
|
||||
/// assert_eq!(set.insert_merge_overlapping(10..16), Ok(&(10..16)));
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// set.iter().collect::<Vec<_>>(),
|
||||
/// [&(-4..1), &(1..8), &(10..16)]
|
||||
/// );
|
||||
/// ```
|
||||
#[trivial]
|
||||
pub fn insert_merge_overlapping(
|
||||
&mut self,
|
||||
range_bounds: K,
|
||||
) -> Result<&K, TryFromBoundsError>
|
||||
where
|
||||
K: TryFromBounds<I>,
|
||||
{
|
||||
self.map.insert_merge_overlapping(range_bounds, ())
|
||||
}
|
||||
|
||||
/// Adds a new `RangeBounds` to the set and merges into other
|
||||
/// `RangeBounds` in the set which touch or overlap it.
|
||||
///
|
||||
/// If successful then a reference to the newly inserted
|
||||
/// `RangeBounds` is returned.
|
||||
///
|
||||
/// If the merged `RangeBounds` cannot be created with the
|
||||
/// [`TryFromBounds`] trait then a [`TryFromBoundsError`] will be
|
||||
/// returned.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the given `range_bounds` is an invalid
|
||||
/// `RangeBounds`. See [`Invalid
|
||||
/// RangeBounds`](https://docs.rs/range_bounds_map/latest/range_bounds_map/index.html#Invalid-RangeBounds)
|
||||
/// for more details.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use range_bounds_map::RangeBoundsSet;
|
||||
///
|
||||
/// let mut set = RangeBoundsSet::from_slice_strict([1..4]).unwrap();
|
||||
///
|
||||
/// // Touching
|
||||
/// assert_eq!(
|
||||
/// set.insert_merge_touching_or_overlapping(-4..1),
|
||||
/// Ok(&(-4..4))
|
||||
/// );
|
||||
///
|
||||
/// // Overlapping
|
||||
/// assert_eq!(
|
||||
/// set.insert_merge_touching_or_overlapping(2..8),
|
||||
/// Ok(&(-4..8))
|
||||
/// );
|
||||
///
|
||||
/// // Neither Touching or Overlapping
|
||||
/// assert_eq!(
|
||||
/// set.insert_merge_touching_or_overlapping(10..16),
|
||||
/// Ok(&(10..16))
|
||||
/// );
|
||||
///
|
||||
/// assert_eq!(set.iter().collect::<Vec<_>>(), [&(-4..8), &(10..16)]);
|
||||
/// ```
|
||||
#[trivial]
|
||||
pub fn insert_merge_touching_or_overlapping(
|
||||
&mut self,
|
||||
range_bounds: K,
|
||||
) -> Result<&K, TryFromBoundsError>
|
||||
where
|
||||
K: TryFromBounds<I>,
|
||||
{
|
||||
self.map
|
||||
.insert_merge_touching_or_overlapping(range_bounds, ())
|
||||
}
|
||||
|
||||
/// Adds a new `RangeBounds` to the set and overwrites any other
|
||||
/// `RangeBounds` that overlap the given `RangeBounds`.
|
||||
///
|
||||
/// This is equivalent to using [`RangeBoundsSet::cut()`]
|
||||
/// followed by [`RangeBoundsSet::insert_strict()`].
|
||||
///
|
||||
/// If the remaining `RangeBounds` left after the cut are not able
|
||||
/// to be created with the [`TryFromBounds`] trait then a
|
||||
/// [`TryFromBoundsError`] will be returned.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the given `range_bounds` is an invalid
|
||||
/// `RangeBounds`. See [`Invalid
|
||||
/// RangeBounds`](https://docs.rs/range_bounds_map/latest/range_bounds_map/index.html#Invalid-RangeBounds)
|
||||
/// for more details.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use range_bounds_map::RangeBoundsSet;
|
||||
///
|
||||
/// let mut set = RangeBoundsSet::from_slice_strict([2..8]).unwrap();
|
||||
///
|
||||
/// assert_eq!(set.insert_overwrite(4..6), Ok(()));
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// set.iter().collect::<Vec<_>>(),
|
||||
/// [&(2..4), &(4..6), &(6..8)]
|
||||
/// );
|
||||
/// ```
|
||||
#[trivial]
|
||||
pub fn insert_overwrite(
|
||||
&mut self,
|
||||
range_bounds: K,
|
||||
) -> Result<(), TryFromBoundsError>
|
||||
where
|
||||
K: TryFromBounds<I>,
|
||||
{
|
||||
self.map.insert_overwrite(range_bounds, ())
|
||||
}
|
||||
|
||||
/// Returns the first `RangeBounds` in the set, if any.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use range_bounds_map::RangeBoundsSet;
|
||||
///
|
||||
/// let set = RangeBoundsSet::from_slice_strict([1..4, 4..8, 8..100])
|
||||
/// .unwrap();
|
||||
///
|
||||
/// assert_eq!(set.first(), Some(&(1..4)));
|
||||
/// ```
|
||||
#[trivial]
|
||||
pub fn first(&self) -> Option<&K> {
|
||||
self.map.first_entry().map(|(key, _)| key)
|
||||
}
|
||||
|
||||
/// Returns the last `RangeBounds` in the set, if any.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use range_bounds_map::RangeBoundsSet;
|
||||
///
|
||||
/// let set = RangeBoundsSet::from_slice_strict([1..4, 4..8, 8..100])
|
||||
/// .unwrap();
|
||||
///
|
||||
/// assert_eq!(set.last(), Some(&(8..100)));
|
||||
/// ```
|
||||
#[trivial]
|
||||
pub fn last(&self) -> Option<&K> {
|
||||
self.map.last_entry().map(|(key, _)| key)
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, K> IntoIterator for RangeBoundsSet<I, K>
|
||||
where
|
||||
K: RangeBounds<I>,
|
||||
I: Ord + Clone,
|
||||
{
|
||||
type Item = K;
|
||||
type IntoIter = IntoIter<I, K>;
|
||||
#[trivial]
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
return IntoIter {
|
||||
inner: self.map.into_iter(),
|
||||
};
|
||||
}
|
||||
}
|
||||
/// An owning iterator over the entries of a [`RangeBoundsSet`].
|
||||
///
|
||||
/// This `struct` is created by the [`into_iter`] method on
|
||||
/// [`RangeBoundsSet`] (provided by the [`IntoIterator`] trait). See
|
||||
/// its documentation for more.
|
||||
///
|
||||
/// [`into_iter`]: IntoIterator::into_iter
|
||||
/// [`IntoIterator`]: core::iter::IntoIterator
|
||||
pub struct IntoIter<I, K> {
|
||||
inner: MapIntoIter<I, K, ()>,
|
||||
}
|
||||
impl<I, K> Iterator for IntoIter<I, K> {
|
||||
type Item = K;
|
||||
#[trivial]
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.inner.next().map(first)
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, K> Default for RangeBoundsSet<I, K>
|
||||
where
|
||||
I: Ord,
|
||||
{
|
||||
#[trivial]
|
||||
fn default() -> Self {
|
||||
RangeBoundsSet {
|
||||
map: RangeBoundsMap::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, K> Serialize for RangeBoundsSet<I, K>
|
||||
where
|
||||
I: Ord + Clone,
|
||||
K: RangeBounds<I> + Serialize,
|
||||
{
|
||||
#[trivial]
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let mut seq = serializer.serialize_seq(Some(self.len()))?;
|
||||
for range_bounds in self.iter() {
|
||||
seq.serialize_element(&range_bounds)?;
|
||||
}
|
||||
seq.end()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, I, K> Deserialize<'de> for RangeBoundsSet<I, K>
|
||||
where
|
||||
K: Deserialize<'de> + RangeBounds<I>,
|
||||
I: Ord + Clone,
|
||||
{
|
||||
#[trivial]
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_seq(RangeBoundsSetVisitor {
|
||||
i: PhantomData,
|
||||
k: PhantomData,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
struct RangeBoundsSetVisitor<I, K> {
|
||||
i: PhantomData<I>,
|
||||
k: PhantomData<K>,
|
||||
}
|
||||
|
||||
impl<'de, I, K> Visitor<'de> for RangeBoundsSetVisitor<I, K>
|
||||
where
|
||||
I: Ord + Clone,
|
||||
K: RangeBounds<I> + Deserialize<'de>,
|
||||
{
|
||||
type Value = RangeBoundsSet<I, K>;
|
||||
|
||||
#[trivial]
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("a RangeBoundsSet")
|
||||
}
|
||||
|
||||
#[trivial]
|
||||
fn visit_seq<A>(self, mut access: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: SeqAccess<'de>,
|
||||
{
|
||||
let mut set = RangeBoundsSet::new();
|
||||
while let Some(range_bounds) = access.next_element()? {
|
||||
set.insert_strict(range_bounds)
|
||||
.map_err(|_| serde::de::Error::custom("RangeBounds overlap"))?;
|
||||
}
|
||||
Ok(set)
|
||||
}
|
||||
}
|
||||
|
||||
#[trivial]
|
||||
fn first<A, B>((a, _): (A, B)) -> A {
|
||||
a
|
||||
|
||||
+52
-20
@@ -1,44 +1,76 @@
|
||||
use std::ops::Bound;
|
||||
use std::ops::{Bound, RangeBounds};
|
||||
|
||||
pub type TestBounds = (Bound<u8>, Bound<u8>);
|
||||
use crate::{TryFromBounds, TryFromBoundsError};
|
||||
|
||||
pub type TestBounds = (Bound<i8>, Bound<i8>);
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn uu() -> TestBounds {
|
||||
(Bound::Unbounded, Bound::Unbounded)
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
pub fn ui(x: u8) -> TestBounds {
|
||||
pub fn ui(x: i8) -> TestBounds {
|
||||
(Bound::Unbounded, Bound::Included(x))
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
pub fn ue(x: u8) -> TestBounds {
|
||||
pub fn ue(x: i8) -> TestBounds {
|
||||
(Bound::Unbounded, Bound::Excluded(x))
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
pub fn iu(x: u8) -> TestBounds {
|
||||
pub fn iu(x: i8) -> TestBounds {
|
||||
(Bound::Included(x), Bound::Unbounded)
|
||||
}
|
||||
//fn eu(x: u8) -> TestBounds {
|
||||
//fn eu(x: i8) -> TestBounds {
|
||||
//(Bound::Excluded(x), Bound::Unbounded)
|
||||
//}
|
||||
#[allow(dead_code)]
|
||||
pub fn ii(x1: u8, x2: u8) -> TestBounds {
|
||||
pub fn ii(x1: i8, x2: i8) -> TestBounds {
|
||||
(Bound::Included(x1), Bound::Included(x2))
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
pub fn ie(x1: u8, x2: u8) -> TestBounds {
|
||||
pub fn ie(x1: i8, x2: i8) -> TestBounds {
|
||||
(Bound::Included(x1), Bound::Excluded(x2))
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
pub fn ei(x1: u8, x2: u8) -> TestBounds {
|
||||
pub fn ei(x1: i8, x2: i8) -> TestBounds {
|
||||
(Bound::Excluded(x1), Bound::Included(x2))
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
pub fn ee(x1: u8, x2: u8) -> TestBounds {
|
||||
pub fn ee(x1: i8, x2: i8) -> TestBounds {
|
||||
(Bound::Excluded(x1), Bound::Excluded(x2))
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn u() -> Bound<u8> {
|
||||
pub fn u() -> Bound<i8> {
|
||||
Bound::Unbounded
|
||||
}
|
||||
|
||||
/// a..b Inclusive-Exclusive range struct
|
||||
/// since the builtin range isn't Copy for some reason
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct InExRange {
|
||||
start: i8,
|
||||
end: i8,
|
||||
}
|
||||
|
||||
pub fn ran(start: i8, end: i8) -> InExRange {
|
||||
InExRange { start, end }
|
||||
}
|
||||
|
||||
impl RangeBounds<i8> for InExRange {
|
||||
fn start_bound(&self) -> Bound<&i8> {
|
||||
Bound::Included(&self.start)
|
||||
}
|
||||
fn end_bound(&self) -> Bound<&i8> {
|
||||
Bound::Excluded(&self.end)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFromBounds<i8> for InExRange {
|
||||
fn try_from_bounds(
|
||||
start_bound: Bound<i8>,
|
||||
end_bound: Bound<i8>,
|
||||
) -> Result<Self, crate::TryFromBoundsError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
match (start_bound, end_bound) {
|
||||
(Bound::Included(start), Bound::Excluded(end)) => {
|
||||
Ok(InExRange { start, end })
|
||||
}
|
||||
_ => Err(TryFromBoundsError),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user