diff --git a/src/lib.rs b/src/lib.rs index e6385f5..46b0d30 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -61,8 +61,12 @@ along with range_bounds_map. If not, see . //! impl RangeBounds for Reservation { //! fn start_bound(&self) -> Bound<&u8> { //! match self { -//! Reservation::Finite(start, _) => Bound::Included(start), -//! Reservation::Infinite(start) => Bound::Excluded(start), +//! Reservation::Finite(start, _) => { +//! Bound::Included(start) +//! } +//! Reservation::Infinite(start) => { +//! Bound::Excluded(start) +//! } //! } //! } //! fn end_bound(&self) -> Bound<&u8> { @@ -80,15 +84,21 @@ along with range_bounds_map. If not, see . //! ]) //! .unwrap(); //! -//! for (reservation, name) in reservation_map.overlapping(&(16..17)) { -//! println!("{name} has reserved {reservation:?} inside the range 16..17"); +//! for (reservation, name) in reservation_map.overlapping(&(16..17)) +//! { +//! println!( +//! "{name} has reserved {reservation:?} inside the range 16..17" +//! ); //! } //! //! for (reservation, name) in reservation_map.iter() { //! println!("{name} has reserved {reservation:?}"); //! } //! -//! assert_eq!(reservation_map.overlaps(&Reservation::Infinite(0)), true); +//! assert_eq!( +//! reservation_map.overlaps(&Reservation::Infinite(0)), +//! true +//! ); //! ``` //! //! # How @@ -161,7 +171,7 @@ along with range_bounds_map. If not, see . //! - //! A data structure based off of a 2007 published paper! It supports any //! RangeBounds as keys too, except it is implemented with a non-balancing -//! Box based tree, however it also supports overlapping +//! `Box` based tree, however it also supports overlapping //! RangeBounds which my library does not. //! - //! I'm not entirely sure what this library is or isn't, but it looks like diff --git a/src/range_bounds_map.rs b/src/range_bounds_map.rs index 4062b52..8fc0c31 100644 --- a/src/range_bounds_map.rs +++ b/src/range_bounds_map.rs @@ -103,7 +103,7 @@ use crate::bounds::StartBound; /// ); /// /// assert_eq!( -/// map.get_key_value_at_point(&NotNan::new(2.0).unwrap()), +/// map.get_range_bounds_value_at_point(&NotNan::new(2.0).unwrap()), /// Some((&ExEx::new(0.0, 5.0), &8)) /// ); /// ``` @@ -120,18 +120,55 @@ where K: RangeBounds, I: Ord + Clone, { + /// Makes a new, empty `RangeBoundsMap`. + /// + /// # Examples + /// ``` + /// use std::ops::Range; + /// + /// use range_bounds_map::RangeBoundsMap; + /// + /// let range_bounds_map: RangeBoundsMap, bool> = + /// RangeBoundsMap::new(); + /// ``` pub fn new() -> Self { RangeBoundsMap { starts: BTreeMap::new(), } } + /// Returns the number of `RangeBounds` in the map. + /// + /// # Examples + /// ``` + /// use range_bounds_map::RangeBoundsMap; + /// + /// let mut range_bounds_map = RangeBoundsMap::new(); + /// + /// assert_eq!(range_bounds_map.len(), 0); + /// range_bounds_map.insert(0..1, false).unwrap(); + /// assert_eq!(range_bounds_map.len(), 1); + /// ``` pub fn len(&self) -> usize { self.starts.len() } - //returns Err(()) if the given range overlaps another range - //does not coalesce ranges if they touch + /// Adds a new (`RangeBounds` `Value`) pair to the map. + /// + /// If the new `RangeBounds` overlaps one or more `RangeBounds` + /// already in the set then `Err(())` is returned and the map is + /// not updated. + /// + /// # Examples + /// ``` + /// use range_bounds_map::RangeBoundsMap; + /// + /// let mut range_bounds_map = RangeBoundsMap::new(); + /// + /// assert_eq!(range_bounds_map.insert(5..10, 9), Ok(())); + /// assert_eq!(range_bounds_map.insert(5..10, 2), Err(())); + /// assert_eq!(range_bounds_map.len(), 1); + /// ``` pub fn insert(&mut self, range_bounds: K, value: V) -> Result<(), ()> { if self.overlaps(&range_bounds) { return Err(()); @@ -148,10 +185,23 @@ where return Ok(()); } - pub fn contains_point(&self, point: &I) -> bool { - self.get_at_point(point).is_some() - } - + /// Returns `true` if the given `RangeBounds` overlaps any of the + /// `RangeBounds` in the map. + /// + /// # Examples + /// ``` + /// use range_bounds_map::RangeBoundsMap; + /// + /// let mut range_bounds_map = RangeBoundsMap::new(); + /// + /// range_bounds_map.insert(5..10, false); + /// + /// assert_eq!(range_bounds_map.overlaps(&(1..=3)), false); + /// assert_eq!(range_bounds_map.overlaps(&(4..5)), false); + /// + /// assert_eq!(range_bounds_map.overlaps(&(4..=5)), true); + /// assert_eq!(range_bounds_map.overlaps(&(4..6)), true); + /// ``` pub fn overlaps(&self, search_range_bounds: &Q) -> bool where Q: RangeBounds, @@ -159,6 +209,27 @@ where self.overlapping(search_range_bounds).next().is_some() } + /// Returns an iterator over every (`RangeBounds`, `Value`) pair + /// in the map which overlap the given `search_range_bounds` in + /// ascending order. + /// + /// # Examples + /// ``` + /// use range_bounds_map::RangeBoundsMap; + /// + /// let range_bounds_map = RangeBoundsMap::try_from([ + /// (1..4, false), + /// (4..8, true), + /// (8..100, false), + /// ]) + /// .unwrap(); + /// + /// let mut overlapping = range_bounds_map.overlapping(&(2..8)); + /// + /// assert_eq!(overlapping.next(), Some((&(1..4), &false))); + /// assert_eq!(overlapping.next(), Some((&(4..8), &true))); + /// assert_eq!(overlapping.next(), None); + /// ``` pub fn overlapping( &self, search_range_bounds: &Q, @@ -214,13 +285,71 @@ where ); } + /// Returns a reference to the `Value` corresponding to the + /// `RangeBounds` in the set that overlaps the given point, if + /// any. + /// + /// # Examples + /// ``` + /// use range_bounds_map::RangeBoundsMap; + /// + /// let range_bounds_map = RangeBoundsMap::try_from([ + /// (1..4, false), + /// (4..8, true), + /// (8..100, false), + /// ]) + /// .unwrap(); + /// + /// assert_eq!(range_bounds_map.get_at_point(&3), Some(&false)); + /// assert_eq!(range_bounds_map.get_at_point(&4), Some(&true)); + /// assert_eq!(range_bounds_map.get_at_point(&101), None); + /// ``` pub fn get_at_point(&self, point: &I) -> Option<&V> { - self.get_key_value_at_point(point).map(|(_, value)| value) + self.get_range_bounds_value_at_point(point) + .map(|(_, value)| value) } + /// Returns `true` if the map contains a `RangeBounds` that + /// overlaps a given point, and `false` if not. + /// + /// # Examples + /// ``` + /// use range_bounds_map::RangeBoundsMap; + /// + /// let range_bounds_map = RangeBoundsMap::try_from([ + /// (1..4, false), + /// (4..8, true), + /// (8..100, false), + /// ]) + /// .unwrap(); + /// + /// assert_eq!(range_bounds_map.contains_point(&3), true); + /// assert_eq!(range_bounds_map.contains_point(&4), true); + /// assert_eq!(range_bounds_map.contains_point(&101), false); + /// ``` + pub fn contains_point(&self, point: &I) -> bool { + self.get_at_point(point).is_some() + } + + /// Returns a mutable reference to the `Value` corresponding to + /// the `RangeBounds` that overlaps the given point, if any. + /// + /// # Examples + /// ``` + /// use range_bounds_map::RangeBoundsMap; + /// + /// let mut range_bounds_map = + /// RangeBoundsMap::try_from([(1..4, false)]).unwrap(); + /// + /// if let Some(x) = range_bounds_map.get_at_point_mut(&2) { + /// *x = true; + /// } + /// + /// assert_eq!(range_bounds_map.get_at_point(&1), Some(&true)); + /// ``` pub fn get_at_point_mut(&mut self, point: &I) -> Option<&mut V> { if let Some(overlapping_start_bound) = self - .get_key_value_at_point(point) + .get_range_bounds_value_at_point(point) .map(|(key, _)| key.start_bound()) { return self @@ -232,7 +361,28 @@ where return None; } - pub fn get_key_value_at_point(&self, point: &I) -> Option<(&K, &V)> { + /// Returns an (`RangeBounds`, `Value`) pair corresponding to the + /// `RangeBounds` that overlaps the given point, if any. + /// + /// # Examples + /// ``` + /// use range_bounds_map::RangeBoundsMap; + /// + /// let range_bounds_map = RangeBoundsMap::try_from([ + /// (1..4, false), + /// (4..8, true), + /// (8..100, false), + /// ]) + /// .unwrap(); + /// + /// assert_eq!(range_bounds_map.get_range_bounds_value_at_point(&3), Some((&(1..4), &false))); + /// assert_eq!(range_bounds_map.get_range_bounds_value_at_point(&4), Some((&(4..8), &true))); + /// assert_eq!(range_bounds_map.get_range_bounds_value_at_point(&101), None); + /// ``` + pub fn get_range_bounds_value_at_point( + &self, + point: &I, + ) -> Option<(&K, &V)> { //a zero-range included-included range is equivalent to a point return self .overlapping(&( @@ -242,6 +392,27 @@ where .next(); } + /// Returns an iterator over every (`RangeBounds`, `Value`) pair in the map in + /// ascending order. + /// + /// # Examples + /// ``` + /// use range_bounds_map::RangeBoundsMap; + /// + /// let range_bounds_map = RangeBoundsMap::try_from([ + /// (1..4, false), + /// (4..8, true), + /// (8..100, false), + /// ]) + /// .unwrap(); + /// + /// let mut iter = range_bounds_map.iter(); + /// + /// assert_eq!(iter.next(), Some((&(1..4), &false))); + /// assert_eq!(iter.next(), Some((&(4..8), &true))); + /// assert_eq!(iter.next(), Some((&(8..100), &false))); + /// assert_eq!(iter.next(), None); + /// ``` pub fn iter(&self) -> impl Iterator { self.starts.iter().map(|(_, (key, value))| (key, value)) } diff --git a/src/range_bounds_set.rs b/src/range_bounds_set.rs index bdde7ee..862606f 100644 --- a/src/range_bounds_set.rs +++ b/src/range_bounds_set.rs @@ -28,7 +28,8 @@ use crate::range_bounds_map::RangeBoundsMap; /// use range_bounds_map::RangeBoundsSet; /// /// // Make a set with some ranges -/// let visits = RangeBoundsSet::try_from([4..8, 8..18, 20..100]).unwrap(); +/// let visits = +/// RangeBoundsSet::try_from([4..8, 8..18, 20..100]).unwrap(); /// /// // Check if a point is contained in the set /// if !visits.contains_point(&0) { @@ -104,7 +105,8 @@ where /// /// use range_bounds_map::RangeBoundsSet; /// - /// let range_bounds_set: RangeBoundsSet> = RangeBoundsSet::new(); + /// let range_bounds_set: RangeBoundsSet> = + /// RangeBoundsSet::new(); /// ``` pub fn new() -> Self { RangeBoundsSet { @@ -173,7 +175,7 @@ where } /// Returns an iterator over every `RangeBounds` in the set which - /// overlaps the given `search_range_bounds` in ascending order. + /// overlap the given `search_range_bounds` in ascending order. /// /// # Examples /// ``` @@ -215,7 +217,7 @@ where /// assert_eq!(range_bounds_set.get_at_point(&101), None); /// ``` pub fn get_at_point(&self, point: &I) -> Option<&K> { - self.map.get_key_value_at_point(point).map(|(key, _)| key) + self.map.get_range_bounds_value_at_point(point).map(|(key, _)| key) } /// Returns `true` if the set contains a `RangeBounds` that @@ -236,7 +238,7 @@ where self.map.contains_point(point) } - /// Returns an iterator over every `RangeBouns` in the set in + /// Returns an iterator over every `RangeBounds` in the set in /// ascending order. /// /// # Examples @@ -246,10 +248,11 @@ where /// let range_bounds_set = /// RangeBoundsSet::try_from([1..4, 4..8, 8..100]).unwrap(); /// - /// let mut iter = range_bounds_set.overlapping(&(2..8)); + /// let mut iter = range_bounds_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); /// ``` pub fn iter(&self) -> impl Iterator {