added range_bound_map.rs main examples and documentation
This commit is contained in:
parent
53b13cbd4f
commit
78dff0d99e
10
README.md
10
README.md
@ -6,10 +6,6 @@
|
||||
|
||||
- add examples for all functions in rust doc comments and test them with cargo doc-test
|
||||
|
||||
- add some actual rust example files in an example folder
|
||||
|
||||
- convert README to cool format using links to docs
|
||||
|
||||
- add github badges including lib.rs
|
||||
- make logo
|
||||
|
||||
@ -19,14 +15,12 @@
|
||||
|
||||
- use it in robot_Sweet_graph for a bit before publishing
|
||||
|
||||
- copy docs from set to map and update appropriately
|
||||
|
||||
- update lines of code figures on docs
|
||||
|
||||
- make all functions' trait bounds specific instead of at impl level
|
||||
|
||||
- convert all examples not using `from` to use `from`, and tests
|
||||
|
||||
- turn overlaps back into a trait to make it public, mabye
|
||||
|
||||
- review caveats again
|
||||
|
||||
- run cargo fmt
|
||||
|
@ -4,3 +4,6 @@ hard_tabs=true
|
||||
imports_granularity="Module"
|
||||
group_imports="StdExternalCrate"
|
||||
max_width=80
|
||||
format_code_in_doc_comments=true
|
||||
doc_comment_code_block_width=70
|
||||
unstable_features = true
|
||||
|
49
src/lib.rs
49
src/lib.rs
@ -45,53 +45,52 @@ along with range_bounds_map. If not, see <https://www.gnu.org/licenses/>.
|
||||
//!
|
||||
//! # Example using a custom [`RangeBounds`] type
|
||||
//! ```
|
||||
//! use std::ops::RangeBounds;
|
||||
//! use std::ops::Bound;
|
||||
//! use std::ops::{Bound, RangeBounds};
|
||||
//!
|
||||
//! use range_bounds_map::RangeBoundsMap;
|
||||
//!
|
||||
//! #[derive(Debug)]
|
||||
//! enum Reservation {
|
||||
//! // Start, End (Inclusive-Inclusive)
|
||||
//! Finite(u8, u8),
|
||||
//! // Start (Exclusive)
|
||||
//! Infinite(u8)
|
||||
//! // Start, End (Inclusive-Inclusive)
|
||||
//! Finite(u8, u8),
|
||||
//! // Start (Exclusive)
|
||||
//! Infinite(u8),
|
||||
//! }
|
||||
//!
|
||||
//! // First, we need to implement RangeBounds
|
||||
//! impl RangeBounds<u8> for Reservation {
|
||||
//! fn start_bound(&self) -> Bound<&u8> {
|
||||
//! match self {
|
||||
//! Reservation::Finite(start, _) => Bound::Included(start),
|
||||
//! Reservation::Infinite(start) => Bound::Excluded(start),
|
||||
//! }
|
||||
//! }
|
||||
//! fn end_bound(&self) -> Bound<&u8> {
|
||||
//! match self {
|
||||
//! Reservation::Finite(_, end) => Bound::Included(end),
|
||||
//! Reservation::Infinite(_) => Bound::Unbounded,
|
||||
//! }
|
||||
//! }
|
||||
//! fn start_bound(&self) -> Bound<&u8> {
|
||||
//! match self {
|
||||
//! Reservation::Finite(start, _) => Bound::Included(start),
|
||||
//! Reservation::Infinite(start) => Bound::Excluded(start),
|
||||
//! }
|
||||
//! }
|
||||
//! fn end_bound(&self) -> Bound<&u8> {
|
||||
//! match self {
|
||||
//! Reservation::Finite(_, end) => Bound::Included(end),
|
||||
//! Reservation::Infinite(_) => Bound::Unbounded,
|
||||
//! }
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! // Next we can create a custom typed RangeBoundsMap
|
||||
//! let reservation_map = RangeBoundsMap::try_from([
|
||||
//! (Reservation::Finite(10, 20), "Ferris".to_string()),
|
||||
//! (Reservation::Infinite(20), "Corro".to_string()),
|
||||
//! ]).unwrap();
|
||||
//! (Reservation::Finite(10, 20), "Ferris".to_string()),
|
||||
//! (Reservation::Infinite(20), "Corro".to_string()),
|
||||
//! ])
|
||||
//! .unwrap();
|
||||
//!
|
||||
//! for (reservation, name) in reservation_map.overlapping(&(16..17)) {
|
||||
//! println!("{name} has reserved {reservation:?} inside the range 16..17");
|
||||
//! println!("{name} has reserved {reservation:?} inside the range 16..17");
|
||||
//! }
|
||||
//!
|
||||
//! for (reservation, name) in reservation_map.iter() {
|
||||
//! println!("{name} has reserved {reservation:?}");
|
||||
//! println!("{name} has reserved {reservation:?}");
|
||||
//! }
|
||||
//!
|
||||
//! assert_eq!(reservation_map.overlaps(&Reservation::Infinite(0)), true);
|
||||
//! ```
|
||||
//!
|
||||
//!
|
||||
//! # How
|
||||
//!
|
||||
//! Most of the [`RangeBounds`]-specific methods on [`RangeBoundsMap`]
|
||||
@ -173,7 +172,7 @@ along with range_bounds_map. If not, see <https://www.gnu.org/licenses/>.
|
||||
//!
|
||||
//! [`BTreeMap`]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html
|
||||
//! [`BTreeSet`]: https://doc.rust-lang.org/std/collections/struct.BTreeSet.html
|
||||
//! [`RangeBounds`]: https://doc.rust-lang.org/std/collections/struct.BTreeSet.html
|
||||
//! [`RangeBounds`]: https://doc.rust-lang.org/std/ops/trait.RangeBounds.html
|
||||
//! [`start_bound()`]: https://doc.rust-lang.org/std/ops/trait.RangeBounds.html#tymethod.start_bound
|
||||
//! [`end_bound()`]: https://doc.rust-lang.org/std/ops/trait.RangeBounds.html#tymethod.end_bound
|
||||
//! [`Range`]: https://doc.rust-lang.org/std/ops/struct.Range.html
|
||||
|
@ -26,6 +26,91 @@ use either::Either;
|
||||
|
||||
use crate::bounds::StartBound;
|
||||
|
||||
/// An ordered map of [`RangeBounds`] based on [`BTreeMap`]
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use range_bounds_map::RangeBoundsMap;
|
||||
///
|
||||
/// // Make a map of ranges to booleans
|
||||
/// let mut map = RangeBoundsMap::try_from([
|
||||
/// (4..8, false),
|
||||
/// (8..18, true),
|
||||
/// (20..100, false),
|
||||
/// ])
|
||||
/// .unwrap();
|
||||
///
|
||||
/// // Change a value in the map
|
||||
/// *map.get_at_point_mut(&(7)).unwrap() = true;
|
||||
///
|
||||
/// // Get a value in the map
|
||||
/// if map.contains_point(&99) {
|
||||
/// println!("Map contains value at 99 :)");
|
||||
/// }
|
||||
///
|
||||
/// // Iterate over the entries in the map
|
||||
/// for (range, value) in map.iter() {
|
||||
/// println!("{range:?}, {value:?}");
|
||||
/// }
|
||||
/// ```
|
||||
/// Example using a custom [`RangeBounds`] type:
|
||||
/// ```
|
||||
/// use std::ops::{Bound, RangeBounds};
|
||||
///
|
||||
/// use ordered_float::NotNan;
|
||||
/// use range_bounds_map::RangeBoundsMap;
|
||||
///
|
||||
/// // 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 [`RangeBoundsMap`] of [`ExEx`]s to `u8`
|
||||
/// let mut map = RangeBoundsMap::new();
|
||||
///
|
||||
/// map.insert(ExEx::new(0.0, 5.0), 8).unwrap();
|
||||
/// map.insert(ExEx::new(5.0, 7.5), 32).unwrap();
|
||||
///
|
||||
/// 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_key_value_at_point(&NotNan::new(2.0).unwrap()),
|
||||
/// Some((&ExEx::new(0.0, 5.0), &8))
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
/// [`RangeBounds`]: https://doc.rust-lang.org/std/ops/trait.RangeBounds.html
|
||||
/// [`BTreeMap`]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html
|
||||
#[derive(Debug)]
|
||||
pub struct RangeBoundsMap<I, K, V> {
|
||||
starts: BTreeMap<StartBound<I>, (K, V)>,
|
||||
}
|
||||
@ -41,9 +126,9 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.starts.len()
|
||||
}
|
||||
pub fn len(&self) -> usize {
|
||||
self.starts.len()
|
||||
}
|
||||
|
||||
//returns Err(()) if the given range overlaps another range
|
||||
//does not coalesce ranges if they touch
|
||||
|
@ -31,21 +31,20 @@ use crate::range_bounds_map::RangeBoundsMap;
|
||||
/// 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) {
|
||||
/// println!("No visit at the beginning ;(");
|
||||
/// if !visits.contains_point(&0) {
|
||||
/// println!("No visit at the beginning ;(");
|
||||
/// }
|
||||
///
|
||||
/// // Iterate over the ranges overlapping another range
|
||||
/// for visit in visits.overlapping(&(2..=8)) {
|
||||
/// println!("{visit:?}");
|
||||
/// println!("{visit:?}");
|
||||
/// }
|
||||
/// ```
|
||||
/// Example using a custom [`RangeBounds`] type:
|
||||
/// ```
|
||||
/// use std::ops::Bound;
|
||||
/// use std::ops::RangeBounds;
|
||||
/// use ordered_float::NotNan;
|
||||
/// 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
|
||||
@ -53,8 +52,8 @@ use crate::range_bounds_map::RangeBoundsMap;
|
||||
/// // We use [`ordered_float::NotNan`]s as the inner type must be Ord
|
||||
/// // similar to a normal [`BTreeSet`]
|
||||
/// struct ExEx {
|
||||
/// start: NotNan<f32>,
|
||||
/// end: NotNan<f32>,
|
||||
/// start: NotNan<f32>,
|
||||
/// end: NotNan<f32>,
|
||||
/// }
|
||||
/// # impl ExEx {
|
||||
/// # fn new(start: f32, end: f32) -> ExEx {
|
||||
@ -67,12 +66,12 @@ use crate::range_bounds_map::RangeBoundsMap;
|
||||
///
|
||||
/// // 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)
|
||||
/// }
|
||||
/// 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
|
||||
@ -81,12 +80,12 @@ use crate::range_bounds_map::RangeBoundsMap;
|
||||
/// set.insert(ExEx::new(0.0, 5.0)).unwrap();
|
||||
/// set.insert(ExEx::new(5.0, 7.5)).unwrap();
|
||||
///
|
||||
/// assert_eq!(set.contains_point(&(NotNan::new(5.0).unwrap())), false);
|
||||
/// assert_eq!(set.contains_point(&(NotNan::new(7.0).unwrap())), true);
|
||||
/// assert_eq!(set.contains_point(&(NotNan::new(7.5).unwrap())), false);
|
||||
/// assert_eq!(set.contains_point(&NotNan::new(5.0).unwrap()), false);
|
||||
/// assert_eq!(set.contains_point(&NotNan::new(7.0).unwrap()), true);
|
||||
/// assert_eq!(set.contains_point(&NotNan::new(7.5).unwrap()), false);
|
||||
/// ```
|
||||
///
|
||||
/// [`RangeBounds`]: https://doc.rust-lang.org/std/collections/struct.BTreeSet.html
|
||||
/// [`RangeBounds`]: https://doc.rust-lang.org/std/ops/trait.RangeBounds.html
|
||||
/// [`BTreeSet`]: https://doc.rust-lang.org/std/collections/struct.BTreeSet.html
|
||||
pub struct RangeBoundsSet<I, K> {
|
||||
map: RangeBoundsMap<I, K, ()>,
|
||||
@ -102,6 +101,7 @@ where
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use std::ops::Range;
|
||||
///
|
||||
/// use range_bounds_map::RangeBoundsSet;
|
||||
///
|
||||
/// let range_bounds_set: RangeBoundsSet<u8, Range<u8>> = RangeBoundsSet::new();
|
||||
@ -179,7 +179,8 @@ where
|
||||
/// ```
|
||||
/// use range_bounds_map::RangeBoundsSet;
|
||||
///
|
||||
/// let range_bounds_set = RangeBoundsSet::try_from([1..4, 4..8, 8..100]).unwrap();
|
||||
/// let range_bounds_set =
|
||||
/// RangeBoundsSet::try_from([1..4, 4..8, 8..100]).unwrap();
|
||||
///
|
||||
/// let mut overlapping = range_bounds_set.overlapping(&(2..8));
|
||||
///
|
||||
@ -206,7 +207,8 @@ where
|
||||
/// ```
|
||||
/// use range_bounds_map::RangeBoundsSet;
|
||||
///
|
||||
/// let range_bounds_set = RangeBoundsSet::try_from([1..4, 4..8, 8..100]).unwrap();
|
||||
/// let range_bounds_set =
|
||||
/// RangeBoundsSet::try_from([1..4, 4..8, 8..100]).unwrap();
|
||||
///
|
||||
/// assert_eq!(range_bounds_set.get_at_point(&3), Some(&(1..4)));
|
||||
/// assert_eq!(range_bounds_set.get_at_point(&4), Some(&(4..8)));
|
||||
@ -223,7 +225,8 @@ where
|
||||
/// ```
|
||||
/// use range_bounds_map::RangeBoundsSet;
|
||||
///
|
||||
/// let range_bounds_set = RangeBoundsSet::try_from([1..4, 4..8, 8..100]).unwrap();
|
||||
/// let range_bounds_set =
|
||||
/// RangeBoundsSet::try_from([1..4, 4..8, 8..100]).unwrap();
|
||||
///
|
||||
/// assert_eq!(range_bounds_set.contains_point(&3), true);
|
||||
/// assert_eq!(range_bounds_set.contains_point(&4), true);
|
||||
@ -240,7 +243,8 @@ where
|
||||
/// ```
|
||||
/// use range_bounds_map::RangeBoundsSet;
|
||||
///
|
||||
/// let range_bounds_set = RangeBoundsSet::try_from([1..4, 4..8, 8..100]).unwrap();
|
||||
/// let range_bounds_set =
|
||||
/// RangeBoundsSet::try_from([1..4, 4..8, 8..100]).unwrap();
|
||||
///
|
||||
/// let mut iter = range_bounds_set.overlapping(&(2..8));
|
||||
///
|
||||
|
Loading…
x
Reference in New Issue
Block a user