From ad57a3ff0343f64a1e9a16769125927680a0984e Mon Sep 17 00:00:00 2001 From: ripytide Date: Tue, 2 Jan 2024 19:19:12 +0000 Subject: [PATCH 1/2] mass rename for #47 --- CHANGELOG.md | 2 + Cargo.lock | 22 +- Cargo.toml | 12 +- README.md | 61 +- src/discrete_finite.rs | 8 +- src/discrete_range_set.rs | 306 ------- src/{inclusive_interval.rs => interval.rs} | 162 ++-- src/lib.rs | 109 +-- src/{discrete_range_map.rs => map.rs} | 958 ++++++++++----------- src/set.rs | 306 +++++++ src/utils.rs | 80 +- 11 files changed, 1014 insertions(+), 1012 deletions(-) delete mode 100644 src/discrete_range_set.rs rename src/{inclusive_interval.rs => interval.rs} (54%) rename src/{discrete_range_map.rs => map.rs} (62%) create mode 100644 src/set.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 5eab0bf..ceb5736 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 documentation for use by end-users, #56 - `insert_overwrite()` now returns the cut entries, #51 - Renamed `gaps()` to `gaps_trimmed()` and added a `gaps_untrimmed()` method +- Mass replaced renamed from the word "range" to the word "interval" all code + items, docs. ### Fixed diff --git a/Cargo.lock b/Cargo.lock index c20971b..f5a8fdc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -24,17 +24,6 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" -[[package]] -name = "discrete_range_map" -version = "0.6.2" -dependencies = [ - "btree_monstrousity", - "either", - "itertools", - "pretty_assertions", - "serde", -] - [[package]] name = "either" version = "1.9.0" @@ -50,6 +39,17 @@ dependencies = [ "either", ] +[[package]] +name = "nodit" +version = "0.6.2" +dependencies = [ + "btree_monstrousity", + "either", + "itertools", + "pretty_assertions", + "serde", +] + [[package]] name = "pretty_assertions" version = "1.4.0" diff --git a/Cargo.toml b/Cargo.toml index 2dc0d4e..6ebbb04 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,17 +1,17 @@ [package] -name = "discrete_range_map" +name = "nodit" version = "0.6.2" authors = ["James Forster "] edition = "2021" description = """ -This crate provides DiscreteRangeMap and DiscreteRangeSet, Data -Structures for storing non-overlapping discrete intervals based off +This crate provides NoditMap and NoditSet, Data +Structures for storing Non-Overlapping Discrete Intervals based off BTreeMap. """ -documentation = "https://docs.rs/discrete_range_map" +documentation = "https://docs.rs/nodit" readme = "README.md" -homepage = "https://github.com/ripytide/discrete_range_map" -repository = "https://github.com/ripytide/discrete_range_map" +homepage = "https://github.com/ripytide/nodit" +repository = "https://github.com/ripytide/nodit" license = "AGPL-3.0-or-later" keywords = ["data-structures", "map", "data", "library"] categories = ["data-structures"] diff --git a/README.md b/README.md index c1588e0..fa0c1cc 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,35 @@ -# discrete_range_map +# nodit -[![License](https://img.shields.io/github/license/ripytide/discrete_range_map)](https://www.gnu.org/licenses/agpl-3.0.en.html) -[![Docs](https://docs.rs/discrete_range_map/badge.svg)](https://docs.rs/discrete_range_map) -[![Maintained](https://img.shields.io/maintenance/yes/2023)](https://github.com/ripytide) -[![Crates.io](https://img.shields.io/crates/v/discrete_range_map)](https://crates.io/crates/discrete_range_map) +[![License](https://img.shields.io/github/license/ripytide/nodit)](https://www.gnu.org/licenses/agpl-3.0.en.html) +[![Docs](https://docs.rs/nodit/badge.svg)](https://docs.rs/nodit) +[![Maintained](https://img.shields.io/maintenance/yes/2024)](https://github.com/ripytide) +[![Crates.io](https://img.shields.io/crates/v/nodit)](https://crates.io/crates/nodit)

-discrete_range_map_logo +nodit_logo

-This crate provides [`DiscreteRangeMap`] and [`DiscreteRangeSet`], -Data Structures for storing non-overlapping discrete intervals based -off [`BTreeMap`]. +This crate provides [`NoditMap`] and [`NoditSet`], Data Structures for storing +non-overlapping discrete intervals based off [`BTreeMap`]. `no_std` is supported and should work with the default features. ## `Copy` is partially required Due to implementation complications with non-`Copy` types the -datastructures currently require both the range type and the points the +data-structures currently require both the range type and the points the ranges are over to be `Copy`. However, the value type used when using -the [`DiscreteRangeMap`] does not have to be `Copy`. In fact the only +the [`NoditMap`] does not have to be `Copy`. In fact the only required traits on the value type are sometimes `Clone` or `Eq` but only for some methods so if in doubt check a methods trait bounds. ## Example using an Inclusive-Exclusive range ```rust -use discrete_range_map::inclusive_interval::ie; -use discrete_range_map::DiscreteRangeMap; +use nodit::interval::ie; +use nodit::NoditMap; -let mut map = DiscreteRangeMap::new(); +let mut map = NoditMap::new(); map.insert_strict(ie(0, 5), true); map.insert_strict(ie(5, 10), false); @@ -45,9 +44,9 @@ assert_eq!(map.contains_point(5), true); ```rust use std::ops::{Bound, RangeBounds}; -use discrete_range_map::inclusive_interval::ie; -use discrete_range_map::{ - DiscreteFinite, DiscreteRangeMap, InclusiveInterval, +use nodit::interval::ie; +use nodit::{ + DiscreteFinite, NoditMap, InclusiveInterval, InclusiveRange, }; @@ -75,9 +74,9 @@ impl InclusiveRange for Reservation { } } -// Second, we need to implement From> -impl From> for Reservation { - fn from(value: InclusiveInterval) -> Self { +// Second, we need to implement From> +impl From> for Reservation { + fn from(value: Interval) -> Self { if value.end == i8::MAX { Reservation::Infinite(value.start) } else { @@ -89,8 +88,8 @@ impl From> for Reservation { } } -// Next we can create a custom typed DiscreteRangeMap -let reservation_map = DiscreteRangeMap::from_slice_strict([ +// Next we can create a custom typed NoditMap +let reservation_map = NoditMap::from_slice_strict([ (Reservation::Finite(10, 20), "Ferris".to_string()), (Reservation::Infinite(21), "Corro".to_string()), ]) @@ -149,7 +148,7 @@ as this: ```rust use std::cmp::Ordering; -use discrete_range_map::DiscreteFinite; +use nodit::DiscreteFinite; #[derive(Debug, Clone, Copy, PartialEq, Eq)] enum WithInfinity { @@ -227,19 +226,19 @@ where // Infinity is encountered such as when it might be // returned by `get_entry_at_point()`, for example: -use discrete_range_map::{DiscreteRangeMap, InclusiveInterval}; +use nodit::{NoditMap, Interval}; -let map: DiscreteRangeMap< +let map: NoditMap< WithInfinity, - InclusiveInterval>, + Interval>, bool, -> = DiscreteRangeMap::new(); +> = NoditMap::new(); let mut gap = map.get_entry_at_point(WithInfinity::Finite(4)); assert_eq!( gap, - Err(InclusiveInterval { + Err(Interval { start: WithInfinity::Finite(0), end: WithInfinity::Infinity, }) @@ -363,6 +362,6 @@ topic area, beware my biases when reading: [`range_bounds_map`]: https://docs.rs/range_bounds_map [`bigint`]: https://docs.rs/num-bigint/latest/num_bigint/struct.BigInt.html [`num_bigint`]: https://docs.rs/num-bigint -[`get_entry_at_point()`]: https://docs.rs/discrete_range_map/latest/discrete_range_map/discrete_range_map/struct.DiscreteRangeMap.html#method.get_entry_at_point -[`DiscreteRangeMap`]: https://docs.rs/discrete_range_map/latest/discrete_range_map/discrete_range_map/struct.DiscreteRangeMap.html# -[`DiscreteRangeSet`]: https://docs.rs/discrete_range_map/latest/discrete_range_map/discrete_range_set/struct.DiscreteRangeSet.html# +[`get_entry_at_point()`]: https://docs.rs/nodit/latest/nodit/nodit/struct.NoditMap.html#method.get_entry_at_point +[`NoditMap`]: https://docs.rs/nodit/latest/nodit/nodit/struct.NoditMap.html# +[`NoditSet`]: https://docs.rs/nodit/latest/nodit/discrete_interval_set/struct.NoditSet.html# diff --git a/src/discrete_finite.rs b/src/discrete_finite.rs index ad8d528..b9ae287 100644 --- a/src/discrete_finite.rs +++ b/src/discrete_finite.rs @@ -1,20 +1,20 @@ /* Copyright 2022,2023 James Forster -This file is part of discrete_range_map. +This file is part of nodit. -discrete_range_map is free software: you can redistribute it and/or +nodit 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. -discrete_range_map is distributed in the hope that it will be useful, +nodit 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 discrete_range_map. If not, see . +along with nodit. If not, see . */ //! A module containing the [`DiscreteFinite`] trait and trait impls for the diff --git a/src/discrete_range_set.rs b/src/discrete_range_set.rs deleted file mode 100644 index b951377..0000000 --- a/src/discrete_range_set.rs +++ /dev/null @@ -1,306 +0,0 @@ -/* -Copyright 2022,2023 James Forster - -This file is part of discrete_range_map. - -discrete_range_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. - -discrete_range_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 discrete_range_map. If not, see . -*/ - -//! A module containing [`DiscreteRangeSet`] and related types. -//! -//! Since [`DiscreteRangeSet`] is just a wrapper around -//! [`DiscreteRangeMap`], most of the methods' docs will point towards the -//! equivalent method's docs on [`DiscreteRangeMap`] to prevent -//! inconsistency. - -use core::fmt; -use core::marker::PhantomData; - -use serde::de::{SeqAccess, Visitor}; -use serde::ser::SerializeSeq; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; - -use crate::discrete_range_map::IntoIter as DiscreteRangeMapIntoIter; -use crate::{DiscreteRangeMap, OverlapError, PointType, RangeType}; - -/// An ordered set of non-overlapping ranges based on [`DiscreteRangeMap`]. -/// -/// `I` is the generic type parameter for the [`Ord`] type the `K` -/// type is range over. -/// -/// `K` is the generic type parameter for the range implementing type -/// in the set. -/// -/// Phrasing it another way: `I` is the point type and `K` is the range type. -/// -/// See [`DiscreteRangeMap`] for more details. -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct DiscreteRangeSet { - inner: DiscreteRangeMap, -} - -impl DiscreteRangeSet -where - I: PointType, - K: RangeType, -{ - /// See [`DiscreteRangeMap::overlaps()`] for more details. - pub fn overlaps(&self, range: Q) -> bool - where - Q: RangeType, - { - self.inner.overlaps(range) - } - /// See [`DiscreteRangeMap::overlapping()`] for more details. - pub fn overlapping( - &self, - range: Q, - ) -> impl DoubleEndedIterator - where - Q: RangeType, - { - self.inner.overlapping(range).map(first) - } - /// See [`DiscreteRangeMap::get_entry_at_point()`] for more details. - pub fn get_at_point(&self, point: I) -> Result<&K, K> { - self.inner.get_entry_at_point(point).map(first) - } - /// See [`DiscreteRangeMap::contains_point()`] for more details. - pub fn contains_point(&self, point: I) -> bool { - self.inner.contains_point(point) - } - /// See [`DiscreteRangeMap::remove_overlapping()`] for more details. - pub fn remove_overlapping<'a, Q>( - &'a mut self, - range: Q, - ) -> impl Iterator - where - Q: RangeType + 'a, - { - self.inner.remove_overlapping(range).map(first) - } - /// See [`DiscreteRangeMap::cut()`] for more details. - pub fn cut<'a, Q>(&'a mut self, range: Q) -> impl Iterator - where - Q: RangeType + 'a, - { - self.inner.cut(range).map(first) - } - /// See [`DiscreteRangeMap::gaps_untrimmed()`] for more details. - pub fn gaps_untrimmed<'a, Q>( - &'a self, - range: Q, - ) -> impl Iterator + '_ - where - Q: RangeType + 'a, - { - self.inner.gaps_untrimmed(range) - } - /// See [`DiscreteRangeMap::gaps_trimmed()`] for more details. - pub fn gaps_trimmed<'a, Q>( - &'a self, - range: Q, - ) -> impl Iterator + '_ - where - Q: RangeType + 'a, - { - self.inner.gaps_trimmed(range) - } - /// See [`DiscreteRangeMap::contains_entire_range()`] for more details. - pub fn contains_entire_range(&self, range: Q) -> bool - where - Q: RangeType, - { - self.inner.contains_entire_range(range) - } - /// See [`DiscreteRangeMap::insert_strict()`] for more details. - pub fn insert_strict(&mut self, range: K) -> Result<(), OverlapError<()>> { - self.inner.insert_strict(range, ()) - } - /// See [`DiscreteRangeMap::insert_merge_touching()`] for more details. - pub fn insert_merge_touching( - &mut self, - range: K, - ) -> Result> { - self.inner.insert_merge_touching(range, ()) - } - /// See [`DiscreteRangeMap::insert_merge_overlapping()`] for more details. - pub fn insert_merge_overlapping(&mut self, range: K) -> K { - self.inner.insert_merge_overlapping(range, ()) - } - /// See [`DiscreteRangeMap::insert_merge_touching_or_overlapping()`] for more details. - pub fn insert_merge_touching_or_overlapping(&mut self, range: K) -> K { - self.inner.insert_merge_touching_or_overlapping(range, ()) - } - /// See [`DiscreteRangeMap::insert_overwrite()`] for more details. - pub fn insert_overwrite(&mut self, range: K) -> impl Iterator { - self.inner.insert_overwrite(range, ()).map(first) - } - /// See [`DiscreteRangeMap::from_slice_strict()`] for more details. - pub fn from_slice_strict( - slice: [K; N], - ) -> Result, OverlapError<()>> { - let mut set = DiscreteRangeSet::new(); - for range in slice { - set.insert_strict(range)?; - } - return Ok(set); - } - /// See [`DiscreteRangeMap::from_iter_strict()`] for more details. - pub fn from_iter_strict( - iter: impl Iterator, - ) -> Result, OverlapError<()>> { - let mut set = DiscreteRangeSet::new(); - for range in iter { - set.insert_strict(range)?; - } - return Ok(set); - } -} - -impl DiscreteRangeSet { - /// See [`DiscreteRangeMap::new()`] for more details. - pub fn new() -> Self { - DiscreteRangeSet { - inner: DiscreteRangeMap::new(), - } - } - /// See [`DiscreteRangeMap::len()`] for more details. - pub fn len(&self) -> usize { - self.inner.len() - } - /// See [`DiscreteRangeMap::is_empty()`] for more details. - pub fn is_empty(&self) -> bool { - self.inner.is_empty() - } - /// See [`DiscreteRangeMap::iter()`] for more details. - pub fn iter(&self) -> impl DoubleEndedIterator { - self.inner.iter().map(first) - } - /// See [`DiscreteRangeMap::first_entry()`] for more details. - pub fn first(&self) -> Option<&K> { - self.inner.first_entry().map(first) - } - /// See [`DiscreteRangeMap::last_entry()`] for more details. - pub fn last(&self) -> Option<&K> { - self.inner.last_entry().map(first) - } -} - -// Helper Functions ========================== - -fn first((a, _): (A, B)) -> A { - a -} - -// Trait Impls ========================== - -impl IntoIterator for DiscreteRangeSet { - type Item = K; - type IntoIter = IntoIter; - fn into_iter(self) -> Self::IntoIter { - return IntoIter { - inner: self.inner.into_iter(), - }; - } -} -/// An owning iterator over the entries of a [`DiscreteRangeSet`]. -/// -/// This `struct` is created by the [`into_iter`] method on -/// [`DiscreteRangeSet`] (provided by the [`IntoIterator`] trait). See -/// its documentation for more. -/// -/// [`into_iter`]: IntoIterator::into_iter -/// [`IntoIterator`]: core::iter::IntoIterator -pub struct IntoIter { - inner: DiscreteRangeMapIntoIter, -} -impl Iterator for IntoIter { - type Item = K; - fn next(&mut self) -> Option { - self.inner.next().map(first) - } -} - -impl Default for DiscreteRangeSet -where - I: PointType, -{ - fn default() -> Self { - DiscreteRangeSet { - inner: DiscreteRangeMap::default(), - } - } -} - -impl Serialize for DiscreteRangeSet -where - K: Serialize, -{ - fn serialize(&self, serializer: S) -> Result - 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 DiscreteRangeSet -where - I: PointType, - K: RangeType + Deserialize<'de>, -{ - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - deserializer.deserialize_seq(DiscreteRangeSetVisitor { - i: PhantomData, - k: PhantomData, - }) - } -} - -struct DiscreteRangeSetVisitor { - i: PhantomData, - k: PhantomData, -} - -impl<'de, I, K> Visitor<'de> for DiscreteRangeSetVisitor -where - I: PointType, - K: RangeType + Deserialize<'de>, -{ - type Value = DiscreteRangeSet; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("a DiscreteRangeSet") - } - - fn visit_seq(self, mut access: A) -> Result - where - A: SeqAccess<'de>, - { - let mut set = DiscreteRangeSet::new(); - while let Some(range_bounds) = access.next_element()? { - set.insert_strict(range_bounds) - .map_err(|_| serde::de::Error::custom("ranges overlap"))?; - } - Ok(set) - } -} diff --git a/src/inclusive_interval.rs b/src/interval.rs similarity index 54% rename from src/inclusive_interval.rs rename to src/interval.rs index ab6458b..7cc303c 100644 --- a/src/inclusive_interval.rs +++ b/src/interval.rs @@ -1,20 +1,20 @@ /* Copyright 2022,2023 James Forster -This file is part of discrete_range_map. +This file is part of nodit. -discrete_range_map is free software: you can redistribute it and/or +nodit 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. -discrete_range_map is distributed in the hope that it will be useful, +nodit 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 discrete_range_map. If not, see . +along with nodit. If not, see . */ //! A module containing [`InclusiveInterval`] and its constructors. @@ -29,8 +29,8 @@ use core::ops::{Bound, Range, RangeBounds, RangeInclusive}; use serde::{Deserialize, Serialize}; -use crate::discrete_range_map::invalid_range_panic; -use crate::{InclusiveRange, PointType}; +use crate::map::invalid_interval_panic; +use crate::{InclusiveInterval, PointType}; /// An inclusive interval, only valid intervals can be constructed. /// @@ -39,13 +39,13 @@ use crate::{InclusiveRange, PointType}; /// their own interval types. /// /// To create an `InclusiveInterval` use one of the various contrutor -/// functions which will all panic if you try to create an invalid range. +/// functions which will all panic if you try to create an invalid interval. /// See [`Invalid -/// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges) +/// Intervals`](https://docs.rs/nodit/latest/nodit/index.html#invalid-intervals) /// for more details. /// /// ``` -/// use discrete_range_map::inclusive_interval::{ee, ii}; +/// use nodit::interval::{ee, ii}; /// /// let inclusive_interval = ii(4, 4); /// let exclusive_interval = ee(3, 5); @@ -54,35 +54,35 @@ use crate::{InclusiveRange, PointType}; /// ``` /// /// ```should_panic -/// use discrete_range_map::inclusive_interval::ee; +/// use nodit::interval::ee; /// /// let invalid_interval = ee(4, 4); /// ``` #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] -pub struct InclusiveInterval { +pub struct Interval { /// The start of the interval, inclusive. pub(crate) start: I, /// The end of the interval, inclusive. pub(crate) end: I, } -impl InclusiveInterval +impl Interval where I: PointType, { - /// The start of the range, inclusive. + /// The start of the interval, inclusive. /// /// ``` - /// use discrete_range_map::inclusive_interval::ii; + /// use nodit::interval::ii; /// /// assert_eq!(ii(2, 4).start(), 2); /// ``` pub fn start(&self) -> I { self.start } - /// The end of the range, inclusive. + /// The end of the interval, inclusive. /// /// ``` - /// use discrete_range_map::inclusive_interval::ii; + /// use nodit::interval::ii; /// /// assert_eq!(ii(2, 4).end(), 4); /// ``` @@ -91,7 +91,7 @@ where } } -impl RangeBounds for InclusiveInterval +impl RangeBounds for Interval where I: PointType, { @@ -103,7 +103,7 @@ where Bound::Included(&self.end) } } -impl InclusiveRange for InclusiveInterval +impl InclusiveInterval for Interval where I: PointType, { @@ -115,12 +115,12 @@ where self.end } } -impl From> for RangeInclusive { - fn from(value: InclusiveInterval) -> Self { +impl From> for RangeInclusive { + fn from(value: Interval) -> Self { value.start..=value.end } } -impl From> for InclusiveInterval +impl From> for Interval where I: PointType, { @@ -128,15 +128,15 @@ where ii(*value.start(), *value.end()) } } -impl From> for Range +impl From> for Range where I: PointType, { - fn from(value: InclusiveInterval) -> Self { + fn from(value: Interval) -> Self { value.start..value.end.up().unwrap() } } -impl From> for InclusiveInterval +impl From> for Interval where I: PointType, { @@ -149,29 +149,29 @@ where /// /// # Panics /// -/// Panics if the range is an invalid range. See [`Invalid -/// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges) +/// Panics if the interval is an invalid interval. See [`Invalid +/// Intervals`](https://docs.rs/nodit/latest/nodit/index.html#invalid-intervals) /// for more details. /// /// ``` -/// use discrete_range_map::inclusive_interval::uu; -/// use discrete_range_map::InclusiveInterval; +/// use nodit::interval::uu; +/// use nodit::{Interval, InclusiveInterval}; /// -/// let interval1: InclusiveInterval = uu(); -/// let interval2: InclusiveInterval = uu(); +/// let interval1: Interval = uu(); +/// let interval2: Interval = uu(); /// /// assert_eq!(interval1, interval2) /// ``` -pub fn uu() -> InclusiveInterval +pub fn uu() -> Interval where I: PointType, { - let interval = InclusiveInterval { + let interval = Interval { start: I::MIN, end: I::MAX, }; - invalid_range_panic(interval); + invalid_interval_panic(interval); interval } @@ -179,28 +179,28 @@ where /// /// # Panics /// -/// Panics if the range is an invalid range. See [`Invalid -/// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges) +/// Panics if the interval is an invalid interval. See [`Invalid +/// Intervals`](https://docs.rs/nodit/latest/nodit/index.html#invalid-intervals) /// for more details. /// /// ``` -/// use discrete_range_map::inclusive_interval::ui; +/// use nodit::interval::ui; /// /// let interval1 = ui(1); /// let interval2 = ui(4); /// /// assert_ne!(interval1, interval2) /// ``` -pub fn ui(x: I) -> InclusiveInterval +pub fn ui(x: I) -> Interval where I: PointType, { - let interval = InclusiveInterval { + let interval = Interval { start: I::MIN, end: x, }; - invalid_range_panic(interval); + invalid_interval_panic(interval); interval } @@ -208,28 +208,28 @@ where /// /// # Panics /// -/// Panics if the range is an invalid range. See [`Invalid -/// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges) +/// Panics if the interval is an invalid interval. See [`Invalid +/// Intervals`](https://docs.rs/nodit/latest/nodit/index.html#invalid-intervals) /// for more details. /// /// ``` -/// use discrete_range_map::inclusive_interval::ue; +/// use nodit::interval::ue; /// /// let interval1 = ue(1); /// let interval2 = ue(4); /// /// assert_ne!(interval1, interval2) /// ``` -pub fn ue(x: I) -> InclusiveInterval +pub fn ue(x: I) -> Interval where I: PointType, { - let interval = InclusiveInterval { + let interval = Interval { start: I::MIN, end: x.down().unwrap(), }; - invalid_range_panic(interval); + invalid_interval_panic(interval); interval } @@ -237,28 +237,28 @@ where /// /// # Panics /// -/// Panics if the range is an invalid range. See [`Invalid -/// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges) +/// Panics if the interval is an invalid interval. See [`Invalid +/// Intervals`](https://docs.rs/nodit/latest/nodit/index.html#invalid-intervals) /// for more details. /// /// ``` -/// use discrete_range_map::inclusive_interval::iu; +/// use nodit::interval::iu; /// /// let interval1 = iu(1); /// let interval2 = iu(4); /// /// assert_ne!(interval1, interval2) /// ``` -pub fn iu(x: I) -> InclusiveInterval +pub fn iu(x: I) -> Interval where I: PointType, { - let interval = InclusiveInterval { + let interval = Interval { start: x, end: I::MAX, }; - invalid_range_panic(interval); + invalid_interval_panic(interval); interval } @@ -266,28 +266,28 @@ where /// /// # Panics /// -/// Panics if the range is an invalid range. See [`Invalid -/// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges) +/// Panics if the interval is an invalid interval. See [`Invalid +/// Intervals`](https://docs.rs/nodit/latest/nodit/index.html#invalid-intervals) /// for more details. /// /// ``` -/// use discrete_range_map::inclusive_interval::eu; +/// use nodit::interval::eu; /// /// let interval1 = eu(1); /// let interval2 = eu(4); /// /// assert_ne!(interval1, interval2) /// ``` -pub fn eu(x: I) -> InclusiveInterval +pub fn eu(x: I) -> Interval where I: PointType, { - let interval = InclusiveInterval { + let interval = Interval { start: x.up().unwrap(), end: I::MAX, }; - invalid_range_panic(interval); + invalid_interval_panic(interval); interval } @@ -295,25 +295,25 @@ where /// /// # Panics /// -/// Panics if the range is an invalid range. See [`Invalid -/// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges) +/// Panics if the interval is an invalid interval. See [`Invalid +/// Intervals`](https://docs.rs/nodit/latest/nodit/index.html#invalid-intervals) /// for more details. /// /// ``` -/// use discrete_range_map::inclusive_interval::ii; +/// use nodit::interval::ii; /// /// let interval1 = ii(0, 4); /// let interval2 = ii(2, 6); /// /// assert_ne!(interval1, interval2) /// ``` -pub fn ii(x1: I, x2: I) -> InclusiveInterval +pub fn ii(x1: I, x2: I) -> Interval where I: PointType, { - let interval = InclusiveInterval { start: x1, end: x2 }; + let interval = Interval { start: x1, end: x2 }; - invalid_range_panic(interval); + invalid_interval_panic(interval); interval } @@ -321,28 +321,28 @@ where /// /// # Panics /// -/// Panics if the range is an invalid range. See [`Invalid -/// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges) +/// Panics if the interval is an invalid interval. See [`Invalid +/// Intervals`](https://docs.rs/nodit/latest/nodit/index.html#invalid-intervals) /// for more details. /// /// ``` -/// use discrete_range_map::inclusive_interval::ie; +/// use nodit::interval::ie; /// /// let interval1 = ie(0, 4); /// let interval2 = ie(2, 6); /// /// assert_ne!(interval1, interval2) /// ``` -pub fn ie(x1: I, x2: I) -> InclusiveInterval +pub fn ie(x1: I, x2: I) -> Interval where I: PointType, { - let interval = InclusiveInterval { + let interval = Interval { start: x1, end: x2.down().unwrap(), }; - invalid_range_panic(interval); + invalid_interval_panic(interval); interval } @@ -350,28 +350,28 @@ where /// /// # Panics /// -/// Panics if the range is an invalid range. See [`Invalid -/// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges) +/// Panics if the interval is an invalid interval. See [`Invalid +/// Intervals`](https://docs.rs/nodit/latest/nodit/index.html#invalid-intervals) /// for more details. /// /// ``` -/// use discrete_range_map::inclusive_interval::ei; +/// use nodit::interval::ei; /// /// let interval1 = ei(0, 4); /// let interval2 = ei(2, 6); /// /// assert_ne!(interval1, interval2) /// ``` -pub fn ei(x1: I, x2: I) -> InclusiveInterval +pub fn ei(x1: I, x2: I) -> Interval where I: PointType, { - let interval = InclusiveInterval { + let interval = Interval { start: x1.up().unwrap(), end: x2, }; - invalid_range_panic(interval); + invalid_interval_panic(interval); interval } @@ -379,28 +379,28 @@ where /// /// # Panics /// -/// Panics if the range is an invalid range. See [`Invalid -/// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges) +/// Panics if the interval is an invalid interval. See [`Invalid +/// Intervals`](https://docs.rs/nodit/latest/nodit/index.html#invalid-intervals) /// for more details. /// /// ``` -/// use discrete_range_map::inclusive_interval::ee; +/// use nodit::interval::ee; /// /// let interval1 = ee(0, 4); /// let interval2 = ee(2, 6); /// /// assert_ne!(interval1, interval2) /// ``` -pub fn ee(x1: I, x2: I) -> InclusiveInterval +pub fn ee(x1: I, x2: I) -> Interval where I: PointType, { - let interval = InclusiveInterval { + let interval = Interval { start: x1.up().unwrap(), end: x2.down().unwrap(), }; - invalid_range_panic(interval); + invalid_interval_panic(interval); interval } diff --git a/src/lib.rs b/src/lib.rs index f0bc278..257ad29 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,23 +1,23 @@ /* Copyright 2022,2023 James Forster -This file is part of discrete_range_map. +This file is part of nodit. -discrete_range_map is free software: you can redistribute it and/or +nodit 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. -discrete_range_map is distributed in the hope that it will be useful, +nodit 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 discrete_range_map. If not, see . +along with nodit. If not, see . */ -//! This crate provides [`DiscreteRangeMap`] and [`DiscreteRangeSet`], +//! This crate provides [`NoditMap`] and [`NoditSet`], //! Data Structures for storing non-overlapping discrete intervals based //! off [`BTreeMap`]. //! @@ -26,19 +26,19 @@ along with discrete_range_map. If not, see . //! ## `Copy` is partially required //! //! Due to implementation complications with non-`Copy` types the -//! datastructures currently require both the range type and the points the -//! ranges are over to be `Copy`. However, the value type used when using -//! the [`DiscreteRangeMap`] does not have to be `Copy`. In fact the only +//! datastructures currently require both the interval type and the points the +//! intervals are over to be `Copy`. However, the value type used when using +//! the [`NoditMap`] does not have to be `Copy`. In fact the only //! required traits on the value type are sometimes `Clone` or `Eq` but only //! for some methods so if in doubt check a methods trait bounds. //! -//! ## Example using an Inclusive-Exclusive range +//! ## Example using an Inclusive-Exclusive interval //! //! ```rust -//! use discrete_range_map::inclusive_interval::ie; -//! use discrete_range_map::DiscreteRangeMap; +//! use nodit::interval::ie; +//! use nodit::NoditMap; //! -//! let mut map = DiscreteRangeMap::new(); +//! let mut map = NoditMap::new(); //! //! map.insert_strict(ie(0, 5), true); //! map.insert_strict(ie(5, 10), false); @@ -48,15 +48,15 @@ along with discrete_range_map. If not, see . //! assert_eq!(map.contains_point(5), true); //! ``` //! -//! ## Example using a custom range type +//! ## Example using a custom interval type //! //! ```rust //! use std::ops::{Bound, RangeBounds}; //! -//! use discrete_range_map::inclusive_interval::ie; -//! use discrete_range_map::{ -//! DiscreteFinite, DiscreteRangeMap, InclusiveInterval, -//! InclusiveRange, +//! use nodit::interval::ie; +//! use nodit::{ +//! DiscreteFinite, NoditMap, InclusiveInterval, +//! Interval, //! }; //! //! #[derive(Debug, Copy, Clone)] @@ -67,8 +67,8 @@ along with discrete_range_map. If not, see . //! Infinite(i8), //! } //! -//! // First, we need to implement InclusiveRange -//! impl InclusiveRange for Reservation { +//! // First, we need to implement InclusiveInterval +//! impl InclusiveInterval for Reservation { //! fn start(&self) -> i8 { //! match self { //! Reservation::Finite(start, _) => *start, @@ -83,9 +83,9 @@ along with discrete_range_map. If not, see . //! } //! } //! -//! // Second, we need to implement From> -//! impl From> for Reservation { -//! fn from(value: InclusiveInterval) -> Self { +//! // Second, we need to implement From> +//! impl From> for Reservation { +//! fn from(value: Interval) -> Self { //! if value.end() == i8::MAX { //! Reservation::Infinite(value.start()) //! } else { @@ -97,8 +97,8 @@ along with discrete_range_map. If not, see . //! } //! } //! -//! // Next we can create a custom typed DiscreteRangeMap -//! let reservation_map = DiscreteRangeMap::from_slice_strict([ +//! // Next we can create a custom typed NoditMap +//! let reservation_map = NoditMap::from_slice_strict([ //! (Reservation::Finite(10, 20), "Ferris".to_string()), //! (Reservation::Infinite(21), "Corro".to_string()), //! ]) @@ -107,7 +107,7 @@ along with discrete_range_map. If not, see . //! for (reservation, name) in reservation_map.overlapping(ie(16, 17)) //! { //! println!( -//! "{name} has reserved {reservation:?} inside the range 16..17" +//! "{name} has reserved {reservation:?} inside the interval 16..17" //! ); //! } //! @@ -135,7 +135,7 @@ along with discrete_range_map. If not, see . //! `Discrete` but `5.0..=6.0` does **not** touch `7.0..=8.0` since the //! value `6.5` exists. //! -//! Importantly, this also makes Inclusive/Exclusive ended ranges really +//! Importantly, this also makes Inclusive/Exclusive ended intervals really //! easy to work with as they can be losslessly converted between one //! another. For example, `3..6` is equivalent to `3..=5`. //! @@ -157,7 +157,7 @@ along with discrete_range_map. If not, see . //! ```rust //! use std::cmp::Ordering; //! -//! use discrete_range_map::DiscreteFinite; +//! use nodit::DiscreteFinite; //! //! #[derive(Debug, Clone, Copy, PartialEq, Eq)] //! enum WithInfinity { @@ -235,35 +235,35 @@ along with discrete_range_map. If not, see . //! // Infinity is encountered such as when it might be //! // returned by `get_entry_at_point()`, for example: //! -//! use discrete_range_map::inclusive_interval::uu; -//! use discrete_range_map::{DiscreteRangeMap, InclusiveInterval}; +//! use nodit::interval::uu; +//! use nodit::{NoditMap, Interval}; //! -//! let map: DiscreteRangeMap< +//! let map: NoditMap< //! WithInfinity, -//! InclusiveInterval>, +//! Interval>, //! bool, -//! > = DiscreteRangeMap::new(); +//! > = NoditMap::new(); //! //! let mut gap = map.get_entry_at_point(WithInfinity::Finite(4)); //! //! assert_eq!(gap, Err(uu())); //! ``` //! -//! ### Invalid Ranges +//! ### Invalid Intervals //! -//! Within this crate, not all ranges are considered valid ranges. The -//! definition of the validity of a range used within this crate is that a -//! range is only valid if it contains at least one value of the underlying +//! Within this crate, not all intervals are considered valid intervals. The +//! definition of the validity of a interval used within this crate is that a +//! interval is only valid if it contains at least one value of the underlying //! domain. //! //! For example, `4..6` is considered valid as it contains the values `4` //! and `5`, however, `4..4` is considered invalid as it contains no -//! values. Another example of invalid range are those whose start values +//! values. Another example of invalid interval are those whose start values //! are greater than their end values. such as `5..2` or `100..=40`. //! -//! Here are a few examples of ranges and whether they are valid: +//! Here are a few examples of intervals and whether they are valid: //! -//! | range | valid | +//! | interval | valid | //! | -------------------------------------- | ----- | //! | 0..=0 | YES | //! | 0..0 | NO | @@ -274,13 +274,13 @@ along with discrete_range_map. If not, see . //! //! ### Overlap //! -//! Two ranges are "overlapping" if there exists a point that is contained -//! within both ranges. For example, `2..4` and `2..6` overlap but `2..4` +//! Two intervals are "overlapping" if there exists a point that is contained +//! within both intervals. For example, `2..4` and `2..6` overlap but `2..4` //! and `4..8` do not. //! //! ### Touching //! -//! Two ranges are "touching" if they do not overlap and there exists no +//! Two intervals are "touching" if they do not overlap and there exists no //! value between them. For example, `2..4` and `4..6` are touching but //! `2..4` and `6..8` are not, neither are `2..6` and `4..8`. //! @@ -311,7 +311,7 @@ along with discrete_range_map. If not, see . //! topic area, beware my biases when reading: //! //! - -//! Very similar to this crate but can only use [`Range`]s and +//! Very similar to this crate but can only use std [`Range`]s and //! [`RangeInclusive`]s as keys in it's `map` and `set` structs (separately). //! - //! - @@ -321,7 +321,7 @@ along with discrete_range_map. If not, see . //! - //! Allows overlapping intervals but is immutable unfortunately //! - -//! Very similar to rangemap except without a `gaps()` function and only +//! Very similar to `rangemap` except without a `gaps()` function and only //! for [`Range`]s and not [`RangeInclusive`]s. And also no fancy //! merging functions. //! - @@ -366,9 +366,9 @@ along with discrete_range_map. If not, see . //! [`range_bounds_map`]: https://docs.rs/range_bounds_map //! [`bigint`]: https://docs.rs/num-bigint/latest/num_bigint/struct.BigInt.html //! [`num_bigint`]: https://docs.rs/num-bigint -//! [`get_entry_at_point()`]: https://docs.rs/discrete_range_map/latest/discrete_range_map/discrete_range_map/struct.DiscreteRangeMap.html#method.get_entry_at_point -//! [`DiscreteRangeMap`]: https://docs.rs/discrete_range_map/latest/discrete_range_map/discrete_range_map/struct.DiscreteRangeMap.html# -//! [`DiscreteRangeSet`]: https://docs.rs/discrete_range_map/latest/discrete_range_map/discrete_range_set/struct.DiscreteRangeSet.html# +//! [`get_entry_at_point()`]: https://docs.rs/nodit/latest/nodit/nodit/struct.NoditMap.html#method.get_entry_at_point +//! [`NoditMap`]: https://docs.rs/nodit/latest/nodit/nodit/struct.NoditMap.html# +//! [`NoditSet`]: https://docs.rs/nodit/latest/nodit/discrete_interval_set/struct.NoditSet.html# #![feature(let_chains)] #![feature(btree_cursors)] @@ -382,13 +382,14 @@ extern crate alloc; pub(crate) mod utils; pub mod discrete_finite; -pub mod discrete_range_map; -pub mod discrete_range_set; -pub mod inclusive_interval; +pub mod map; +pub mod set; +pub mod interval; pub use crate::discrete_finite::DiscreteFinite; -pub use crate::discrete_range_map::{ - DiscreteRangeMap, InclusiveRange, OverlapError, PointType, RangeType, +pub use crate::map::{ + NoditMap, InclusiveInterval, IntervalType, OverlapError, + PointType, }; -pub use crate::discrete_range_set::DiscreteRangeSet; -pub use crate::inclusive_interval::InclusiveInterval; +pub use crate::set::NoditSet; +pub use crate::interval::Interval; diff --git a/src/discrete_range_map.rs b/src/map.rs similarity index 62% rename from src/discrete_range_map.rs rename to src/map.rs index 03b6ebb..5facce1 100644 --- a/src/discrete_range_map.rs +++ b/src/map.rs @@ -1,23 +1,23 @@ /* Copyright 2022,2023 James Forster -This file is part of discrete_range_map. +This file is part of nodit. -discrete_range_map is free software: you can redistribute it and/or +nodit 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. -discrete_range_map is distributed in the hope that it will be useful, +nodit 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 discrete_range_map. If not, see . +along with nodit. If not, see . */ -//! A module containing [`DiscreteRangeMap`] and related types. +//! A module containing [`NoditMap`] and related types. use alloc::vec::Vec; use core::cmp::Ordering; @@ -35,29 +35,29 @@ use serde::de::{SeqAccess, Visitor}; use serde::ser::SerializeSeq; use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use crate::utils::{cmp_point_with_range, cut_range, overlaps}; -use crate::{DiscreteFinite, InclusiveInterval}; +use crate::utils::{cmp_point_with_interval, cut_interval, overlaps}; +use crate::{DiscreteFinite, Interval}; -/// An ordered map of non-overlapping ranges based on [`BTreeMap`]. +/// An ordered map of non-overlapping intervals based on [`BTreeMap`]. /// /// `I` is the generic type parameter for the [`Ord`] type the `K` -/// type is a range over. +/// type is a interval over. /// -/// `K` is the generic type parameter for the range type stored as the +/// `K` is the generic type parameter for the interval type stored as the /// keys in the map. /// /// `V` is the generic type parameter for the values associated with the /// keys in the map. /// -/// Phrasing it another way: `I` is the point type, `K` is the range type, and `V` is the value type. +/// Phrasing it another way: `I` is the point type, `K` is the interval type, and `V` is the value type. /// /// # Examples /// ``` -/// use discrete_range_map::inclusive_interval::ie; -/// use discrete_range_map::DiscreteRangeMap; +/// use nodit::interval::ie; +/// use nodit::NoditMap; /// -/// // Make a map of ranges to booleans -/// let mut map = DiscreteRangeMap::from_slice_strict([ +/// // Make a map of intervals to booleans +/// let mut map = NoditMap::from_slice_strict([ /// (ie(4, 8), false), /// (ie(8, 18), true), /// (ie(20, 100), false), @@ -72,19 +72,19 @@ use crate::{DiscreteFinite, InclusiveInterval}; /// } /// /// // Iterate over the entries in the map -/// for (range, value) in map.iter() { -/// println!("{range:?}, {value:?}"); +/// for (interval, value) in map.iter() { +/// println!("{interval:?}, {value:?}"); /// } /// ``` /// /// [`BTreeMap`]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html #[derive(Debug, Clone, PartialEq, Eq)] -pub struct DiscreteRangeMap { +pub struct NoditMap { inner: BTreeMap, phantom: PhantomData, } -/// The error returned when inserting a range that overlaps another range when +/// The error returned when inserting a interval that overlaps another interval when /// it should not have. Contains the value that was not inserted. #[derive(PartialEq, Debug)] pub struct OverlapError { @@ -97,39 +97,39 @@ pub struct OverlapError { pub trait PointType: Ord + Copy + DiscreteFinite {} impl PointType for I where I: Ord + Copy + DiscreteFinite {} -/// The marker trait for valid range types, a blanket implementation is provided for all types +/// The marker trait for valid interval types, a blanket implementation is provided for all types /// which implement this traits' super-traits so you shouln't need to implement this yourself. -pub trait RangeType: - InclusiveRange + Copy + From> +pub trait IntervalType: + InclusiveInterval + Copy + From> { } -impl RangeType for K +impl IntervalType for K where I: PointType, - K: InclusiveRange + Copy + From>, + K: InclusiveInterval + Copy + From>, { } -impl DiscreteRangeMap +impl NoditMap where I: PointType, - K: RangeType, + K: IntervalType, { - /// Returns `true` if the given range overlaps any of the - /// other ranges in the map, and `false` if not. + /// Returns `true` if the given interval overlaps any of the + /// other intervals in the map, and `false` if not. /// /// # Panics /// - /// Panics if the given range is an invalid range. See [`Invalid - /// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges) + /// Panics if the given interval is an invalid interval. See [`Invalid + /// Intervals`](https://docs.rs/nodit/latest/nodit/index.html#invalid-intervals) /// for more details. /// /// # Examples /// ``` - /// use discrete_range_map::inclusive_interval::{ie, ii}; - /// use discrete_range_map::DiscreteRangeMap; + /// use nodit::interval::{ie, ii}; + /// use nodit::NoditMap; /// - /// let mut map = DiscreteRangeMap::new(); + /// let mut map = NoditMap::new(); /// /// map.insert_strict(ie(5, 10), false); /// @@ -139,30 +139,30 @@ where /// assert_eq!(map.overlaps(ii(4, 5)), true); /// assert_eq!(map.overlaps(ie(4, 6)), true); /// ``` - pub fn overlaps(&self, range: Q) -> bool + pub fn overlaps(&self, interval: Q) -> bool where - Q: RangeType, + Q: IntervalType, { - invalid_range_panic(range); + invalid_interval_panic(interval); - self.overlapping(range).next().is_some() + self.overlapping(interval).next().is_some() } /// Returns an iterator over every entry in the map that overlaps - /// the given range in ascending order. + /// the given interval in ascending order. /// /// # Panics /// - /// Panics if the given range is an invalid range. See [`Invalid - /// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges) + /// Panics if the given interval is an invalid interval. See [`Invalid + /// Intervals`](https://docs.rs/nodit/latest/nodit/index.html#invalid-intervals) /// for more details. /// /// # Examples /// ``` - /// use discrete_range_map::inclusive_interval::ie; - /// use discrete_range_map::DiscreteRangeMap; + /// use nodit::interval::ie; + /// use nodit::NoditMap; /// - /// let map = DiscreteRangeMap::from_slice_strict([ + /// let map = NoditMap::from_slice_strict([ /// (ie(1, 4), false), /// (ie(4, 8), true), /// (ie(8, 100), false), @@ -178,15 +178,15 @@ where /// ``` pub fn overlapping( &self, - range: Q, + interval: Q, ) -> impl DoubleEndedIterator where - Q: RangeType, + Q: IntervalType, { - invalid_range_panic(range); + invalid_interval_panic(interval); - let start_comp = overlapping_comp(range.start()); - let end_comp = overlapping_comp(range.end()); + let start_comp = overlapping_comp(interval.start()); + let end_comp = overlapping_comp(interval.end()); let start_bound = SearchBoundCustom::Included; let end_bound = SearchBoundCustom::Included; @@ -196,28 +196,28 @@ where } /// Returns an mutable iterator over every entry in the map that - /// overlaps the given range in ascending order. + /// overlaps the given interval in ascending order. /// /// # Panics /// - /// Panics if the given range is an invalid range. See [`Invalid - /// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges) + /// Panics if the given interval is an invalid interval. See [`Invalid + /// Intervals`](https://docs.rs/nodit/latest/nodit/index.html#invalid-intervals) /// for more details. /// /// # Examples /// ``` - /// use discrete_range_map::inclusive_interval::ie; - /// use discrete_range_map::DiscreteRangeMap; + /// use nodit::interval::ie; + /// use nodit::NoditMap; /// - /// let mut map = DiscreteRangeMap::from_slice_strict([ + /// let mut map = NoditMap::from_slice_strict([ /// (ie(1, 4), false), /// (ie(4, 8), true), /// (ie(8, 100), false), /// ]) /// .unwrap(); /// - /// for (range, value) in map.overlapping_mut(ie(3, 7)) { - /// if *range == ie(4, 8) { + /// for (interval, value) in map.overlapping_mut(ie(3, 7)) { + /// if *interval == ie(4, 8) { /// *value = false /// } else { /// *value = true @@ -226,15 +226,15 @@ where /// ``` pub fn overlapping_mut( &mut self, - range: Q, + interval: Q, ) -> impl DoubleEndedIterator where - Q: RangeType, + Q: IntervalType, { - invalid_range_panic(range); + invalid_interval_panic(interval); - let start_comp = overlapping_comp(range.start()); - let end_comp = overlapping_comp(range.end()); + let start_comp = overlapping_comp(interval.start()); + let end_comp = overlapping_comp(interval.end()); let start_bound = SearchBoundCustom::Included; let end_bound = SearchBoundCustom::Included; @@ -243,15 +243,15 @@ where .range_mut(start_comp, start_bound, end_comp, end_bound) } - /// Returns a reference to the value corresponding to the range in + /// Returns a reference to the value corresponding to the interval in /// the map that overlaps the given point, if any. /// /// # Examples /// ``` - /// use discrete_range_map::inclusive_interval::ie; - /// use discrete_range_map::DiscreteRangeMap; + /// use nodit::interval::ie; + /// use nodit::NoditMap; /// - /// let map = DiscreteRangeMap::from_slice_strict([ + /// let map = NoditMap::from_slice_strict([ /// (ie(1, 4), false), /// (ie(4, 8), true), /// (ie(8, 100), false), @@ -267,14 +267,14 @@ where } /// Returns a mutable reference to the value corresponding to the - /// range that overlaps the given point, if any. + /// interval that overlaps the given point, if any. /// /// # Examples /// ``` - /// use discrete_range_map::inclusive_interval::ie; - /// use discrete_range_map::DiscreteRangeMap; + /// use nodit::interval::ie; + /// use nodit::NoditMap; /// let mut map = - /// DiscreteRangeMap::from_slice_strict([(ie(1, 4), false)]) + /// NoditMap::from_slice_strict([(ie(1, 4), false)]) /// .unwrap(); /// /// if let Some(x) = map.get_at_point_mut(2) { @@ -287,15 +287,15 @@ where self.inner.get_mut(overlapping_comp(point)) } - /// Returns `true` if the map contains a range that overlaps the + /// Returns `true` if the map contains a interval that overlaps the /// given point, and `false` if not. /// /// # Examples /// ``` - /// use discrete_range_map::inclusive_interval::ie; - /// use discrete_range_map::DiscreteRangeMap; + /// use nodit::interval::ie; + /// use nodit::NoditMap; /// - /// let map = DiscreteRangeMap::from_slice_strict([ + /// let map = NoditMap::from_slice_strict([ /// (ie(1, 4), false), /// (ie(4, 8), true), /// (ie(8, 100), false), @@ -310,18 +310,18 @@ where self.get_entry_at_point(point).is_ok() } - /// Returns the entry corresponding to the range that + /// Returns the entry corresponding to the interval that /// overlaps the given point, if any. /// - /// If there is no range that overlaps the given point the + /// If there is no interval that overlaps the given point the /// maximally-sized gap at the given point is returned. /// /// # Examples /// ``` - /// use discrete_range_map::inclusive_interval::{ie, iu}; - /// use discrete_range_map::DiscreteRangeMap; + /// use nodit::interval::{ie, iu}; + /// use nodit::NoditMap; /// - /// let map = DiscreteRangeMap::from_slice_strict([ + /// let map = NoditMap::from_slice_strict([ /// (ie(1, 4), false), /// (ie(4, 6), true), /// (ie(8, 100), false), @@ -338,7 +338,7 @@ where .get_key_value(overlapping_comp(point)) .ok_or_else(|| K::from(self.get_gap_at_raw(point))) } - fn get_gap_at_raw(&self, point: I) -> InclusiveInterval { + fn get_gap_at_raw(&self, point: I) -> Interval { let lower = self .inner .upper_bound(overlapping_comp(point), SearchBoundCustom::Included); @@ -346,7 +346,7 @@ where .inner .lower_bound(overlapping_comp(point), SearchBoundCustom::Included); - InclusiveInterval { + Interval { start: lower .key() .map_or(I::MIN, |lower| lower.end().up().unwrap()), @@ -356,21 +356,21 @@ where } } - /// Removes every entry in the map which overlaps the given range + /// Removes every entry in the map which overlaps the given interval /// and returns them in an iterator in ascending order. /// /// # Panics /// - /// Panics if the given range is an invalid range. See [`Invalid - /// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges) + /// Panics if the given interval is an invalid interval. See [`Invalid + /// Intervals`](https://docs.rs/nodit/latest/nodit/index.html#invalid-intervals) /// for more details. /// /// # Examples /// ``` - /// use discrete_range_map::inclusive_interval::ie; - /// use discrete_range_map::DiscreteRangeMap; + /// use nodit::interval::ie; + /// use nodit::NoditMap; /// - /// let mut map = DiscreteRangeMap::from_slice_strict([ + /// let mut map = NoditMap::from_slice_strict([ /// (ie(1, 4), false), /// (ie(4, 8), true), /// (ie(8, 100), false), @@ -391,23 +391,23 @@ where /// ``` pub fn remove_overlapping<'a, Q>( &'a mut self, - range: Q, + interval: Q, ) -> impl Iterator where - Q: RangeType + 'a, + Q: IntervalType + 'a, { - invalid_range_panic(range); + invalid_interval_panic(interval); let mut result = Vec::new(); let mut leftmost_cursor = self.inner.lower_bound_mut( - overlapping_comp(range.start()), + overlapping_comp(interval.start()), SearchBoundCustom::Included, ); while leftmost_cursor .key() - .is_some_and(|inner_range| overlaps(*inner_range, range)) + .is_some_and(|inner_interval| overlaps(*inner_interval, interval)) { result.push(leftmost_cursor.remove_current().unwrap()); } @@ -415,33 +415,33 @@ where return result.into_iter(); } - /// Cuts a given range out of the map and returns an iterator of - /// the full or partial ranges that were cut in ascending order. + /// Cuts a given interval out of the map and returns an iterator of + /// the full or partial intervals that were cut in ascending order. /// /// `V` must implement `Clone` as if you try to cut out the center - /// of a range in the map it will split into two different entries - /// using `Clone`. Or if you partially cut a range then + /// of a interval in the map it will split into two different entries + /// using `Clone`. Or if you partially cut a interval then /// `V` must be cloned to be returned in the iterator. /// /// # Panics /// - /// Panics if the given range is an invalid range. See [`Invalid - /// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges) + /// Panics if the given interval is an invalid interval. See [`Invalid + /// Intervals`](https://docs.rs/nodit/latest/nodit/index.html#invalid-intervals) /// for more details. /// /// # Examples /// ``` - /// use discrete_range_map::inclusive_interval::{ie, ii}; - /// use discrete_range_map::DiscreteRangeMap; + /// use nodit::interval::{ie, ii}; + /// use nodit::NoditMap; /// - /// let mut base = DiscreteRangeMap::from_slice_strict([ + /// let mut base = NoditMap::from_slice_strict([ /// (ie(1, 4), false), /// (ie(4, 8), true), /// (ie(8, 100), false), /// ]) /// .unwrap(); /// - /// let after_cut = DiscreteRangeMap::from_slice_strict([ + /// let after_cut = NoditMap::from_slice_strict([ /// (ie(1, 2), false), /// (ie(40, 100), false), /// ]) @@ -453,15 +453,15 @@ where /// ); /// assert_eq!(base, after_cut); /// ``` - pub fn cut<'a, Q>(&'a mut self, range: Q) -> impl Iterator + pub fn cut<'a, Q>(&'a mut self, interval: Q) -> impl Iterator where - Q: RangeType + 'a, + Q: IntervalType + 'a, V: Clone, { - invalid_range_panic(range); + invalid_interval_panic(interval); - let start_comp = overlapping_comp(range.start()); - let end_comp = overlapping_comp(range.end()); + let start_comp = overlapping_comp(interval.start()); + let end_comp = overlapping_comp(interval.end()); let left_overlapping = self .inner @@ -478,10 +478,10 @@ where && let Some(right) = right_overlapping && left.start() == right.start() { - Either::Left(self.cut_single_overlapping(range, left)) + Either::Left(self.cut_single_overlapping(interval, left)) } else { Either::Right(self.cut_non_single_overlapping( - range, + interval, left_overlapping, right_overlapping, )) @@ -489,21 +489,21 @@ where } fn cut_single_overlapping( &mut self, - range: Q, - single_overlapping_range: K, + interval: Q, + single_overlapping_interval: K, ) -> impl Iterator where - Q: RangeType, + Q: IntervalType, V: Clone, { - invalid_range_panic(range); + invalid_interval_panic(interval); - let cut_result = cut_range(single_overlapping_range, range); + let cut_result = cut_interval(single_overlapping_interval, interval); let returning_before_cut = cut_result.before_cut.map(K::from); let returning_after_cut = cut_result.after_cut.map(K::from); - let value = self.inner.remove(overlapping_comp(range.start())).unwrap(); + let value = self.inner.remove(overlapping_comp(interval.start())).unwrap(); if let Some(before) = returning_before_cut { self.insert_unchecked(before, value.clone()); @@ -516,19 +516,19 @@ where } fn cut_non_single_overlapping<'a, Q>( &'a mut self, - range: Q, + interval: Q, left_overlapping: Option, right_overlapping: Option, ) -> impl Iterator where - Q: RangeType + 'a, + Q: IntervalType + 'a, V: Clone, { - invalid_range_panic(range); + invalid_interval_panic(interval); let (returning_before_cut, keeping_before) = match left_overlapping { Some(before) => { - let cut_result = cut_range(before, range); + let cut_result = cut_interval(before, interval); ( cut_result.before_cut.map(K::from), @@ -539,7 +539,7 @@ where }; let (returning_after_cut, keeping_after) = match right_overlapping { Some(after) => { - let cut_result = cut_range(after, range); + let cut_result = cut_interval(after, interval); ( cut_result.after_cut.map(K::from), @@ -549,8 +549,8 @@ where None => (None, None), }; - let before_value = self.inner.remove(overlapping_comp(range.start())); - let after_value = self.inner.remove(overlapping_comp(range.end())); + let before_value = self.inner.remove(overlapping_comp(interval.start())); + let after_value = self.inner.remove(overlapping_comp(interval.end())); if let Some(returning_before_cut) = returning_before_cut { self.insert_unchecked( @@ -572,9 +572,9 @@ where return keeping_before_entry .into_iter() - .chain(self.remove_overlapping(range).map(|(key, value)| { + .chain(self.remove_overlapping(interval).map(|(key, value)| { ( - K::from(InclusiveInterval { + K::from(Interval { start: key.start(), end: key.end(), }), @@ -585,23 +585,23 @@ where } /// Returns an iterator of all the gaps in the map that overlap the given - /// `range` in ascending order. + /// `interval` in ascending order. /// - /// See [`DiscreteRangeMap::gaps_trimmed()`] if you require the returned - /// gaps to be trimmed to be fully contained within given `range`. + /// See [`NoditMap::gaps_trimmed()`] if you require the returned + /// gaps to be trimmed to be fully contained within given `interval`. /// /// # Panics /// - /// Panics if the given range is an invalid range. See [`Invalid - /// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges) + /// Panics if the given interval is an invalid interval. See [`Invalid + /// Intervals`](https://docs.rs/nodit/latest/nodit/index.html#invalid-intervals) /// for more details. /// /// # Examples /// ``` - /// use discrete_range_map::inclusive_interval::{ie, ii, iu}; - /// use discrete_range_map::DiscreteRangeMap; + /// use nodit::interval::{ie, ii, iu}; + /// use nodit::NoditMap; /// - /// let map = DiscreteRangeMap::from_slice_strict([ + /// let map = NoditMap::from_slice_strict([ /// (ie(1, 3), false), /// (ie(5, 7), true), /// (ie(9, 100), false), @@ -617,21 +617,21 @@ where /// ``` pub fn gaps_untrimmed<'a, Q>( &'a self, - range: Q, + interval: Q, ) -> impl Iterator + '_ where - Q: RangeType + 'a, + Q: IntervalType + 'a, { - invalid_range_panic(range); + invalid_interval_panic(interval); - // If the start or end point of range is not - // contained within a range in the map then we need to + // If the start or end point of interval is not + // contained within a interval in the map then we need to // generate the gaps. let start_gap = - (!self.inner.contains_key(overlapping_comp(range.start()))) - .then(|| self.get_gap_at_raw(range.start())); - let end_gap = (!self.inner.contains_key(overlapping_comp(range.end()))) - .then(|| self.get_gap_at_raw(range.end())); + (!self.inner.contains_key(overlapping_comp(interval.start()))) + .then(|| self.get_gap_at_raw(interval.start())); + let end_gap = (!self.inner.contains_key(overlapping_comp(interval.end()))) + .then(|| self.get_gap_at_raw(interval.end())); let (start_gap, end_gap) = match (start_gap, end_gap) { (Some(start_gap), Some(end_gap)) => { @@ -649,18 +649,18 @@ where }; let overlapping = self - .overlapping(range) + .overlapping(interval) .map(|(key, _)| (key.start(), key.end())); let inner_gaps = overlapping .tuple_windows() .map(|(first, second)| { - K::from(InclusiveInterval { + K::from(Interval { start: first.1.up().unwrap(), end: second.0.down().unwrap(), }) }) - .filter(|range| range.is_valid()); + .filter(|interval| interval.is_valid()); //possibly add the trimmed start and end gaps return start_gap @@ -671,24 +671,24 @@ where } /// Returns an iterator of all the gaps in the map that overlap the given - /// `range` that are also trimmed so they are all fully contained within the - /// given `range`, in ascending order. + /// `interval` that are also trimmed so they are all fully contained within the + /// given `interval`, in ascending order. /// - /// See [`DiscreteRangeMap::gaps_untrimmed()`] if you do not want the + /// See [`NoditMap::gaps_untrimmed()`] if you do not want the /// returned gaps to be trimmed. /// /// # Panics /// - /// Panics if the given range is an invalid range. See [`Invalid - /// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges) + /// Panics if the given interval is an invalid interval. See [`Invalid + /// Intervals`](https://docs.rs/nodit/latest/nodit/index.html#invalid-intervals) /// for more details. /// /// # Examples /// ``` - /// use discrete_range_map::inclusive_interval::{ie, ii, iu}; - /// use discrete_range_map::DiscreteRangeMap; + /// use nodit::interval::{ie, ii, iu}; + /// use nodit::NoditMap; /// - /// let map = DiscreteRangeMap::from_slice_strict([ + /// let map = NoditMap::from_slice_strict([ /// (ie(1, 3), false), /// (ie(5, 7), true), /// (ie(9, 100), false), @@ -704,62 +704,62 @@ where /// ``` pub fn gaps_trimmed<'a, Q>( &'a self, - range: Q, + interval: Q, ) -> impl Iterator + '_ where - Q: RangeType + 'a, + Q: IntervalType + 'a, { - invalid_range_panic(range); + invalid_interval_panic(interval); - // If the start or end point of range is not - // contained within a range in the map then we need to + // If the start or end point of interval is not + // contained within a interval in the map then we need to // generate the gaps. let start_gap = - (!self.inner.contains_key(overlapping_comp(range.start()))) - .then(|| self.get_gap_at_raw(range.start())); - let end_gap = (!self.inner.contains_key(overlapping_comp(range.end()))) - .then(|| self.get_gap_at_raw(range.end())); + (!self.inner.contains_key(overlapping_comp(interval.start()))) + .then(|| self.get_gap_at_raw(interval.start())); + let end_gap = (!self.inner.contains_key(overlapping_comp(interval.end()))) + .then(|| self.get_gap_at_raw(interval.end())); let (trimmed_start_gap, trimmed_end_gap) = match (start_gap, end_gap) { (Some(mut start_gap), Some(mut end_gap)) => { if start_gap.start() == end_gap.start() { //it's the same gap - start_gap.start = range.start(); - start_gap.end = range.end(); + start_gap.start = interval.start(); + start_gap.end = interval.end(); (Some(start_gap), None) } else { //it's different gaps - start_gap.start = range.start(); - end_gap.end = range.end(); + start_gap.start = interval.start(); + end_gap.end = interval.end(); (Some(start_gap), Some(end_gap)) } } (Some(mut start_gap), None) => { - start_gap.start = range.start(); + start_gap.start = interval.start(); (Some(start_gap), None) } (None, Some(mut end_gap)) => { - end_gap.end = range.end(); + end_gap.end = interval.end(); (None, Some(end_gap)) } (None, None) => (None, None), }; let overlapping = self - .overlapping(range) + .overlapping(interval) .map(|(key, _)| (key.start(), key.end())); let inner_gaps = overlapping .tuple_windows() .map(|(first, second)| { - K::from(InclusiveInterval { + K::from(Interval { start: first.1.up().unwrap(), end: second.0.down().unwrap(), }) }) - .filter(|range| range.is_valid()); + .filter(|interval| interval.is_valid()); //possibly add the trimmed start and end gaps return trimmed_start_gap @@ -770,58 +770,58 @@ where } /// Returns `true` if the map covers every point in the given - /// range, and `false` if it does not. + /// interval, and `false` if it does not. /// /// # Panics /// - /// Panics if the given range is an invalid range. See [`Invalid - /// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges) + /// Panics if the given interval is an invalid interval. See [`Invalid + /// Intervals`](https://docs.rs/nodit/latest/nodit/index.html#invalid-intervals) /// for more details. /// /// # Examples /// ``` - /// use discrete_range_map::inclusive_interval::ie; - /// use discrete_range_map::DiscreteRangeMap; + /// use nodit::interval::ie; + /// use nodit::NoditMap; /// - /// let map = DiscreteRangeMap::from_slice_strict([ + /// let map = NoditMap::from_slice_strict([ /// (ie(1, 3), false), /// (ie(5, 8), true), /// (ie(8, 100), false), /// ]) /// .unwrap(); /// - /// assert_eq!(map.contains_entire_range(ie(1, 3)), true); - /// assert_eq!(map.contains_entire_range(ie(2, 6)), false); - /// assert_eq!(map.contains_entire_range(ie(6, 100)), true); + /// assert_eq!(map.contains_entire_interval(ie(1, 3)), true); + /// assert_eq!(map.contains_entire_interval(ie(2, 6)), false); + /// assert_eq!(map.contains_entire_interval(ie(6, 100)), true); /// ``` - pub fn contains_entire_range(&self, range: Q) -> bool + pub fn contains_entire_interval(&self, interval: Q) -> bool where - Q: RangeType, + Q: IntervalType, { - invalid_range_panic(range); + invalid_interval_panic(interval); // Soooo clean and mathematical! - self.gaps_untrimmed(range).next().is_none() + self.gaps_untrimmed(interval).next().is_none() } /// Adds a new entry to the map without modifying other entries. /// - /// If the given range overlaps one or more ranges already in the + /// If the given interval overlaps one or more intervals already in the /// map, then an [`OverlapError`] is returned and the map is not /// updated. /// /// # Panics /// - /// Panics if the given range is an invalid range. See [`Invalid - /// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges) + /// Panics if the given interval is an invalid interval. See [`Invalid + /// Intervals`](https://docs.rs/nodit/latest/nodit/index.html#invalid-intervals) /// for more details. /// /// # Examples /// ``` - /// use discrete_range_map::inclusive_interval::ie; - /// use discrete_range_map::{DiscreteRangeMap, OverlapError}; + /// use nodit::interval::ie; + /// use nodit::{NoditMap, OverlapError}; /// - /// let mut map = DiscreteRangeMap::new(); + /// let mut map = NoditMap::new(); /// /// assert_eq!(map.insert_strict(ie(5, 10), 9), Ok(())); /// assert_eq!( @@ -832,26 +832,26 @@ where /// ``` pub fn insert_strict( &mut self, - range: K, + interval: K, value: V, ) -> Result<(), OverlapError> { - invalid_range_panic(range); + invalid_interval_panic(interval); - if self.overlaps(range) { + if self.overlaps(interval) { return Err(OverlapError { value }); } - self.insert_unchecked(range, value); + self.insert_unchecked(interval, value); return Ok(()); } - fn insert_unchecked(&mut self, range: K, value: V) { - self.inner.insert(range, value, double_comp()); + fn insert_unchecked(&mut self, interval: K, value: V) { + self.inner.insert(interval, value, double_comp()); } fn insert_merge_with_comps( &mut self, - range: K, + interval: K, value: V, get_start: G1, get_end: G2, @@ -864,30 +864,30 @@ where R1: FnOnce(&mut Self, &V), R2: FnOnce(&mut Self, &V), { - invalid_range_panic(range); + invalid_interval_panic(interval); let matching_start = get_start(self, &value); let matching_end = get_end(self, &value); let returning = match (matching_start, matching_end) { (Some(matching_start), Some(matching_end)) => { - K::from(InclusiveInterval { + K::from(Interval { start: matching_start.start(), end: matching_end.end(), }) } - (Some(matching_start), None) => K::from(InclusiveInterval { + (Some(matching_start), None) => K::from(Interval { start: matching_start.start(), - end: range.end(), + end: interval.end(), }), - (None, Some(matching_end)) => K::from(InclusiveInterval { - start: range.start(), + (None, Some(matching_end)) => K::from(Interval { + start: interval.start(), end: matching_end.end(), }), - (None, None) => range, + (None, None) => interval, }; - let _ = self.remove_overlapping(range); + let _ = self.remove_overlapping(interval); remove_start(self, &value); remove_end(self, &value); @@ -897,31 +897,31 @@ where return returning; } - /// Adds a new entry to the map and merges into other ranges in + /// Adds a new entry to the map and merges into other intervals in /// the map which touch it. /// - /// The value of the merged-together range is set to the value given for + /// The value of the merged-together interval is set to the value given for /// this insertion. /// - /// If successful then the newly inserted (possibly merged) range is + /// If successful then the newly inserted (possibly merged) interval is /// returned. /// - /// If the given range overlaps one or more ranges already in the + /// If the given interval overlaps one or more intervals already in the /// map, then an [`OverlapError`] is returned and the map is not /// updated. /// /// # Panics /// - /// Panics if the given range is an invalid range. See [`Invalid - /// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges) + /// Panics if the given interval is an invalid interval. See [`Invalid + /// Intervals`](https://docs.rs/nodit/latest/nodit/index.html#invalid-intervals) /// for more details. /// /// # Examples /// ``` - /// use discrete_range_map::inclusive_interval::ie; - /// use discrete_range_map::{DiscreteRangeMap, OverlapError}; + /// use nodit::interval::ie; + /// use nodit::{NoditMap, OverlapError}; /// - /// let mut map = DiscreteRangeMap::from_slice_strict([ + /// let mut map = NoditMap::from_slice_strict([ /// (ie(1, 4), false), /// (ie(6, 8), true), /// ]) @@ -952,64 +952,64 @@ where /// ``` pub fn insert_merge_touching( &mut self, - range: K, + interval: K, value: V, ) -> Result> { - invalid_range_panic(range); + invalid_interval_panic(interval); - if self.overlaps(range) { + if self.overlaps(interval) { return Err(OverlapError { value }); } Ok(self.insert_merge_with_comps( - range, + interval, value, |selfy, _| { selfy .inner - .get_key_value(touching_start_comp(range.start())) + .get_key_value(touching_start_comp(interval.start())) .map(|(key, _)| key) .copied() }, |selfy, _| { selfy .inner - .get_key_value(touching_end_comp(range.end())) + .get_key_value(touching_end_comp(interval.end())) .map(|(key, _)| key) .copied() }, |selfy, _| { - selfy.inner.remove(touching_start_comp(range.start())); + selfy.inner.remove(touching_start_comp(interval.start())); }, |selfy, _| { - selfy.inner.remove(touching_end_comp(range.end())); + selfy.inner.remove(touching_end_comp(interval.end())); }, )) } - /// Adds a new entry to the map and merges into other ranges in - /// the map which touch it if the touching ranges' values are + /// Adds a new entry to the map and merges into other intervals in + /// the map which touch it if the touching intervals' values are /// equal to the value being inserted. /// - /// If successful then the newly inserted (possibly merged) range is + /// If successful then the newly inserted (possibly merged) interval is /// returned. /// - /// If the given range overlaps one or more ranges already in the + /// If the given interval overlaps one or more intervals already in the /// map, then an [`OverlapError`] is returned and the map is not /// updated. /// /// # Panics /// - /// Panics if the given range is an invalid range. See [`Invalid - /// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges) + /// Panics if the given interval is an invalid interval. See [`Invalid + /// Intervals`](https://docs.rs/nodit/latest/nodit/index.html#invalid-intervals) /// for more details. /// /// # Examples /// ``` - /// use discrete_range_map::inclusive_interval::ie; - /// use discrete_range_map::{DiscreteRangeMap, OverlapError}; + /// use nodit::interval::ie; + /// use nodit::{NoditMap, OverlapError}; /// - /// let mut map = DiscreteRangeMap::from_slice_strict([ + /// let mut map = NoditMap::from_slice_strict([ /// (ie(1, 4), false), /// (ie(6, 8), true), /// ]) @@ -1040,22 +1040,22 @@ where /// ``` pub fn insert_merge_touching_if_values_equal( &mut self, - range: K, + interval: K, value: V, ) -> Result> where V: Eq, { - invalid_range_panic(range); + invalid_interval_panic(interval); - if self.overlaps(range) { + if self.overlaps(interval) { return Err(OverlapError { value }); } let get_start = |selfy: &Self, value: &V| { selfy .inner - .get_key_value(touching_start_comp(range.start())) + .get_key_value(touching_start_comp(interval.start())) .filter(|(_, start_touching_value)| { *start_touching_value == value }) @@ -1065,7 +1065,7 @@ where let get_end = |selfy: &Self, value: &V| { selfy .inner - .get_key_value(touching_end_comp(range.end())) + .get_key_value(touching_end_comp(interval.end())) .filter(|(_, start_touching_value)| { *start_touching_value == value }) @@ -1074,43 +1074,43 @@ where }; Ok(self.insert_merge_with_comps( - range, + interval, value, get_start, get_end, |selfy, value| { if get_start(selfy, value).is_some() { - selfy.inner.remove(touching_start_comp(range.start())); + selfy.inner.remove(touching_start_comp(interval.start())); } }, |selfy, value| { if get_end(selfy, value).is_some() { - selfy.inner.remove(touching_end_comp(range.end())); + selfy.inner.remove(touching_end_comp(interval.end())); } }, )) } - /// Adds a new entry to the map and merges into other ranges in + /// Adds a new entry to the map and merges into other intervals in /// the map which overlap it. /// - /// The value of the merged-together range is set to the value given for + /// The value of the merged-together interval is set to the value given for /// this insertion. /// - /// The newly inserted (possibly merged) range is returned. + /// The newly inserted (possibly merged) interval is returned. /// /// # Panics /// - /// Panics if the given range is an invalid range. See [`Invalid - /// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges) + /// Panics if the given interval is an invalid interval. See [`Invalid + /// Intervals`](https://docs.rs/nodit/latest/nodit/index.html#invalid-intervals) /// for more details. /// /// # Examples /// ``` - /// use discrete_range_map::inclusive_interval::ie; - /// use discrete_range_map::{DiscreteRangeMap, OverlapError}; + /// use nodit::interval::ie; + /// use nodit::{NoditMap, OverlapError}; /// - /// let mut map = DiscreteRangeMap::from_slice_strict([ + /// let mut map = NoditMap::from_slice_strict([ /// (ie(1, 4), false), /// (ie(6, 8), true), /// ]) @@ -1139,23 +1139,23 @@ where /// [(ie(1, 4), false), (ie(4, 8), false), (ie(10, 16), false)] /// ); /// ``` - pub fn insert_merge_overlapping(&mut self, range: K, value: V) -> K { - invalid_range_panic(range); + pub fn insert_merge_overlapping(&mut self, interval: K, value: V) -> K { + invalid_interval_panic(interval); self.insert_merge_with_comps( - range, + interval, value, |selfy, _| { selfy .inner - .get_key_value(overlapping_comp(range.start())) + .get_key_value(overlapping_comp(interval.start())) .map(|(key, _)| key) .copied() }, |selfy, _| { selfy .inner - .get_key_value(overlapping_comp(range.end())) + .get_key_value(overlapping_comp(interval.end())) .map(|(key, _)| key) .copied() }, @@ -1164,26 +1164,26 @@ where ) } - /// Adds a new entry to the map and merges into other ranges in + /// Adds a new entry to the map and merges into other intervals in /// the map which touch or overlap it. /// - /// The value of the merged-together range is set to the value given for + /// The value of the merged-together interval is set to the value given for /// this insertion. /// - /// The newly inserted (possibly merged) range is returned. + /// The newly inserted (possibly merged) interval is returned. /// /// # Panics /// - /// Panics if the given range is an invalid range. See [`Invalid - /// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges) + /// Panics if the given interval is an invalid interval. See [`Invalid + /// Intervals`](https://docs.rs/nodit/latest/nodit/index.html#invalid-intervals) /// for more details. /// /// # Examples /// ``` - /// use discrete_range_map::inclusive_interval::ie; - /// use discrete_range_map::{DiscreteRangeMap, OverlapError}; + /// use nodit::interval::ie; + /// use nodit::{NoditMap, OverlapError}; /// - /// let mut map = DiscreteRangeMap::from_slice_strict([ + /// let mut map = NoditMap::from_slice_strict([ /// (ie(1, 4), false), /// (ie(6, 8), true), /// ]) @@ -1214,68 +1214,68 @@ where /// ``` pub fn insert_merge_touching_or_overlapping( &mut self, - range: K, + interval: K, value: V, ) -> K { - invalid_range_panic(range); + invalid_interval_panic(interval); self.insert_merge_with_comps( - range, + interval, value, |selfy, _| { selfy .inner - .get_key_value(touching_start_comp(range.start())) + .get_key_value(touching_start_comp(interval.start())) .map(|(key, _)| key) .or(selfy .inner - .get_key_value(overlapping_comp(range.start())) + .get_key_value(overlapping_comp(interval.start())) .map(|(key, _)| key)) .copied() }, |selfy, _| { selfy .inner - .get_key_value(touching_end_comp(range.end())) + .get_key_value(touching_end_comp(interval.end())) .map(|(key, _)| key) .or(selfy .inner - .get_key_value(overlapping_comp(range.end())) + .get_key_value(overlapping_comp(interval.end())) .map(|(key, _)| key)) .copied() }, |selfy, _| { - selfy.inner.remove(touching_start_comp(range.start())); + selfy.inner.remove(touching_start_comp(interval.start())); }, |selfy, _| { - selfy.inner.remove(touching_end_comp(range.end())); + selfy.inner.remove(touching_end_comp(interval.end())); }, ) } - /// Adds a new entry to the map and overwrites any other ranges - /// that overlap the new range. + /// Adds a new entry to the map and overwrites any other intervals + /// that overlap the new interval. /// /// Returns an iterator over the full or partial cut entries in /// ascending order. /// - /// This is equivalent to using [`DiscreteRangeMap::cut()`] - /// followed by [`DiscreteRangeMap::insert_strict()`]. Hence the + /// This is equivalent to using [`NoditMap::cut()`] + /// followed by [`NoditMap::insert_strict()`]. Hence the /// same `V: Clone` trait bound applies. /// /// # Panics /// - /// Panics if the given range is an invalid range. See [`Invalid - /// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges) + /// Panics if the given interval is an invalid interval. See [`Invalid + /// Intervals`](https://docs.rs/nodit/latest/nodit/index.html#invalid-intervals) /// for more details. /// /// # Examples /// ``` - /// use discrete_range_map::inclusive_interval::ie; - /// use discrete_range_map::DiscreteRangeMap; + /// use nodit::interval::ie; + /// use nodit::NoditMap; /// /// let mut map = - /// DiscreteRangeMap::from_slice_strict([(ie(2, 8), false)]) + /// NoditMap::from_slice_strict([(ie(2, 8), false)]) /// .unwrap(); /// /// map.insert_overwrite(ie(4, 6), true); @@ -1287,38 +1287,38 @@ where /// ``` pub fn insert_overwrite( &mut self, - range: K, + interval: K, value: V, ) -> impl Iterator where V: Clone, { - invalid_range_panic(range); + invalid_interval_panic(interval); - let cut = self.cut(range); - self.insert_unchecked(range, value); + let cut = self.cut(interval); + self.insert_unchecked(interval, value); cut } - /// Allocates a `DiscreteRangeMap` and moves the given entries from + /// Allocates a `NoditMap` and moves the given entries from /// the given slice into the map using - /// [`DiscreteRangeMap::insert_strict()`]. + /// [`NoditMap::insert_strict()`]. /// /// May return an `Err` while inserting. See - /// [`DiscreteRangeMap::insert_strict()`] for details. + /// [`NoditMap::insert_strict()`] for details. /// /// # Panics /// - /// Panics if the given range is an invalid range. See [`Invalid - /// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges) + /// Panics if the given interval is an invalid interval. See [`Invalid + /// Intervals`](https://docs.rs/nodit/latest/nodit/index.html#invalid-intervals) /// for more details. /// /// # Examples /// ``` - /// use discrete_range_map::inclusive_interval::ie; - /// use discrete_range_map::DiscreteRangeMap; + /// use nodit::interval::ie; + /// use nodit::NoditMap; /// - /// let map = DiscreteRangeMap::from_slice_strict([ + /// let map = NoditMap::from_slice_strict([ /// (ie(1, 4), false), /// (ie(4, 8), true), /// (ie(8, 100), false), @@ -1327,76 +1327,76 @@ where /// ``` pub fn from_slice_strict( slice: [(K, V); N], - ) -> Result, OverlapError> { - let mut map = DiscreteRangeMap::new(); - for (range, value) in slice { - map.insert_strict(range, value)?; + ) -> Result, OverlapError> { + let mut map = NoditMap::new(); + for (interval, value) in slice { + map.insert_strict(interval, value)?; } return Ok(map); } - /// Collects a `DiscreteRangeMap` from an iterator of (range, - /// value) tuples using [`DiscreteRangeMap::insert_strict()`]. + /// Collects a `NoditMap` from an iterator of (interval, + /// value) tuples using [`NoditMap::insert_strict()`]. /// /// May return an `Err` while inserting. See - /// [`DiscreteRangeMap::insert_strict()`] for details. + /// [`NoditMap::insert_strict()`] for details. /// /// # Panics /// - /// Panics if the given range is an invalid range. See [`Invalid - /// Ranges`](https://docs.rs/discrete_range_map/latest/discrete_range_map/index.html#invalid-ranges) + /// Panics if the given interval is an invalid interval. See [`Invalid + /// Intervals`](https://docs.rs/nodit/latest/nodit/index.html#invalid-intervals) /// for more details. /// /// # Examples /// ``` - /// use discrete_range_map::inclusive_interval::ie; - /// use discrete_range_map::DiscreteRangeMap; + /// use nodit::interval::ie; + /// use nodit::NoditMap; /// /// let slice = /// [(ie(1, 4), false), (ie(4, 8), true), (ie(8, 100), false)]; /// - /// let map: DiscreteRangeMap<_, _, _> = - /// DiscreteRangeMap::from_iter_strict( - /// slice.into_iter().filter(|(range, _)| range.start() > 2), + /// let map: NoditMap<_, _, _> = + /// NoditMap::from_iter_strict( + /// slice.into_iter().filter(|(interval, _)| interval.start() > 2), /// ) /// .unwrap(); /// ``` pub fn from_iter_strict( iter: impl Iterator, - ) -> Result, OverlapError> { - let mut map = DiscreteRangeMap::new(); - for (range, value) in iter { - map.insert_strict(range, value)?; + ) -> Result, OverlapError> { + let mut map = NoditMap::new(); + for (interval, value) in iter { + map.insert_strict(interval, value)?; } return Ok(map); } } -impl DiscreteRangeMap { - /// Makes a new, empty `DiscreteRangeMap`. +impl NoditMap { + /// Makes a new, empty `NoditMap`. /// /// # Examples /// ``` - /// use discrete_range_map::{DiscreteRangeMap, InclusiveInterval}; + /// use nodit::{NoditMap, Interval}; /// - /// let map: DiscreteRangeMap, bool> = - /// DiscreteRangeMap::new(); + /// let map: NoditMap, bool> = + /// NoditMap::new(); /// ``` pub fn new() -> Self { - DiscreteRangeMap { + NoditMap { inner: BTreeMap::new(), phantom: PhantomData, } } - /// Returns the number of ranges in the map. + /// Returns the number of intervals in the map. /// /// # Examples /// ``` - /// use discrete_range_map::inclusive_interval::ie; - /// use discrete_range_map::DiscreteRangeMap; + /// use nodit::interval::ie; + /// use nodit::NoditMap; /// - /// let mut map = DiscreteRangeMap::new(); + /// let mut map = NoditMap::new(); /// /// assert_eq!(map.len(), 0); /// map.insert_strict(ie(0, 1), false).unwrap(); @@ -1406,15 +1406,15 @@ impl DiscreteRangeMap { self.inner.len() } - /// Returns `true` if the map contains no ranges, and + /// Returns `true` if the map contains no intervals, and /// `false` if it does. /// /// # Examples /// ``` - /// use discrete_range_map::inclusive_interval::ie; - /// use discrete_range_map::DiscreteRangeMap; + /// use nodit::interval::ie; + /// use nodit::NoditMap; /// - /// let mut map = DiscreteRangeMap::new(); + /// let mut map = NoditMap::new(); /// /// assert_eq!(map.is_empty(), true); /// map.insert_strict(ie(0, 1), false).unwrap(); @@ -1429,10 +1429,10 @@ impl DiscreteRangeMap { /// /// # Examples /// ``` - /// use discrete_range_map::inclusive_interval::ie; - /// use discrete_range_map::DiscreteRangeMap; + /// use nodit::interval::ie; + /// use nodit::NoditMap; /// - /// let map = DiscreteRangeMap::from_slice_strict([ + /// let map = NoditMap::from_slice_strict([ /// (ie(1, 4), false), /// (ie(4, 8), true), /// (ie(8, 100), false), @@ -1455,18 +1455,18 @@ impl DiscreteRangeMap { /// /// # Examples /// ``` - /// use discrete_range_map::inclusive_interval::ie; - /// use discrete_range_map::DiscreteRangeMap; + /// use nodit::interval::ie; + /// use nodit::NoditMap; /// - /// let mut map = DiscreteRangeMap::from_slice_strict([ + /// let mut map = NoditMap::from_slice_strict([ /// (ie(1, 4), false), /// (ie(4, 8), true), /// (ie(8, 100), false), /// ]) /// .unwrap(); /// - /// for (range, value) in map.iter_mut() { - /// if *range == ie(4, 8) { + /// for (interval, value) in map.iter_mut() { + /// if *interval == ie(4, 8) { /// *value = false /// } else { /// *value = true @@ -1483,10 +1483,10 @@ impl DiscreteRangeMap { /// /// # Examples /// ``` - /// use discrete_range_map::inclusive_interval::ie; - /// use discrete_range_map::DiscreteRangeMap; + /// use nodit::interval::ie; + /// use nodit::NoditMap; /// - /// let map = DiscreteRangeMap::from_slice_strict([ + /// let map = NoditMap::from_slice_strict([ /// (ie(1, 4), false), /// (ie(4, 8), true), /// (ie(8, 100), false), @@ -1503,10 +1503,10 @@ impl DiscreteRangeMap { /// /// # Examples /// ``` - /// use discrete_range_map::DiscreteRangeMap; - /// use discrete_range_map::inclusive_interval::ie; + /// use nodit::NoditMap; + /// use nodit::interval::ie; /// - /// let map = DiscreteRangeMap::from_slice_strict([ + /// let map = NoditMap::from_slice_strict([ /// (ie(1, 4), false), /// (ie(4, 8), true), /// (ie(8, 100), false), @@ -1524,14 +1524,14 @@ impl DiscreteRangeMap { // Helper Functions ========================== -pub(crate) fn invalid_range_panic(range: Q) +pub(crate) fn invalid_interval_panic(interval: Q) where I: PointType, - Q: RangeType, + Q: IntervalType, { - if !range.is_valid() { + if !interval.is_valid() { panic!( - "invalid range given to function see here for more details: https://docs.rs/discrete_range_map/latest/discrete_range_map/#invalid-ranges" + "invalid interval given to function see here for more details: https://docs.rs/nodit/latest/nodit/#invalid-intervals" ); } } @@ -1539,23 +1539,23 @@ where fn double_comp() -> impl FnMut(&K, &K) -> Ordering where I: PointType, - K: RangeType, + K: IntervalType, { - |inner_range: &K, new_range: &K| new_range.start().cmp(&inner_range.start()) + |inner_interval: &K, new_interval: &K| new_interval.start().cmp(&inner_interval.start()) } fn overlapping_comp(point: I) -> impl FnMut(&K) -> Ordering where I: PointType, - K: RangeType, + K: IntervalType, { - move |inner_range: &K| cmp_point_with_range(point, *inner_range) + move |inner_interval: &K| cmp_point_with_interval(point, *inner_interval) } fn touching_start_comp(start: I) -> impl FnMut(&K) -> Ordering where I: PointType, - K: RangeType, + K: IntervalType, { - move |inner_range: &K| match inner_range.end().up() { + move |inner_interval: &K| match inner_interval.end().up() { Some(touching_position) => start.cmp(&touching_position), None => Ordering::Less, } @@ -1563,22 +1563,22 @@ where fn touching_end_comp(end: I) -> impl FnMut(&K) -> Ordering where I: PointType, - K: RangeType, + K: IntervalType, { - move |inner_range: &K| match inner_range.start().down() { + move |inner_interval: &K| match inner_interval.start().down() { Some(touching_position) => end.cmp(&touching_position), None => Ordering::Greater, } } -/// A range that has **Inclusive** end-points. -pub trait InclusiveRange { - /// The start of the range, inclusive. +/// A interval that has **Inclusive** end-points. +pub trait InclusiveInterval { + /// The start of the interval, inclusive. fn start(&self) -> I; - /// The end of the range, inclusive. + /// The end of the interval, inclusive. fn end(&self) -> I; - /// Does the range contain the given point? + /// Does the interval contain the given point? fn contains(&self, point: I) -> bool where I: PointType, @@ -1586,7 +1586,7 @@ pub trait InclusiveRange { point >= self.start() && point <= self.end() } - /// Is the range is valid, which according to this crate means `start()` + /// Is the interval is valid, which according to this crate means `start()` /// <= `end()` fn is_valid(&self) -> bool where @@ -1611,16 +1611,16 @@ pub trait InclusiveRange { self.contains(other.start()) || self.contains(other.end()) } - /// Intersect the range with the other one, and return Some if the intersection is not empty. + /// Intersect the interval with the other one, and return Some if the intersection is not empty. fn intersect(&self, other: &Self) -> Option where I: PointType, - Self: From>, + Self: From>, { let intersect_start = I::max(self.start(), other.start()); let intersect_end = I::min(self.end(), other.end()); if intersect_start <= intersect_end { - Some(Self::from(InclusiveInterval { + Some(Self::from(Interval { start: intersect_start, end: intersect_end, })) @@ -1629,20 +1629,20 @@ pub trait InclusiveRange { } } - /// Move the entire range by the given amount. + /// Move the entire interval by the given amount. fn translate(&self, delta: I) -> Self where I: PointType, I: core::ops::Add, - Self: From>, + Self: From>, { - Self::from(InclusiveInterval { + Self::from(Interval { start: self.start() + delta, end: self.end() + delta, }) } - /// The amount between the start and the end points of the range. + /// The amount between the start and the end points of the interval. fn size(&self) -> I where I: PointType, @@ -1654,9 +1654,9 @@ pub trait InclusiveRange { /// Requires that self comes before other fn merge_ordered(&self, other: &Self) -> Self where - Self: From>, + Self: From>, { - Self::from(InclusiveInterval { + Self::from(Interval { start: self.start(), end: other.end(), }) @@ -1665,7 +1665,7 @@ pub trait InclusiveRange { // Trait Impls ========================== -impl IntoIterator for DiscreteRangeMap { +impl IntoIterator for NoditMap { type Item = (K, V); type IntoIter = IntoIter; fn into_iter(self) -> Self::IntoIter { @@ -1675,10 +1675,10 @@ impl IntoIterator for DiscreteRangeMap { }; } } -/// An owning iterator over the entries of a [`DiscreteRangeMap`]. +/// An owning iterator over the entries of a [`NoditMap`]. /// /// This `struct` is created by the [`into_iter`] method on -/// [`DiscreteRangeMap`] (provided by the [`IntoIterator`] trait). See +/// [`NoditMap`] (provided by the [`IntoIterator`] trait). See /// its documentation for more. /// /// [`into_iter`]: IntoIterator::into_iter @@ -1694,16 +1694,16 @@ impl Iterator for IntoIter { } } -impl Default for DiscreteRangeMap { +impl Default for NoditMap { fn default() -> Self { - DiscreteRangeMap { + NoditMap { inner: BTreeMap::default(), phantom: PhantomData, } } } -impl Serialize for DiscreteRangeMap +impl Serialize for NoditMap where K: Serialize, V: Serialize, @@ -1713,24 +1713,24 @@ where S: Serializer, { let mut seq = serializer.serialize_seq(Some(self.len()))?; - for (range_bounds, value) in self.iter() { - seq.serialize_element(&(range_bounds, value))?; + for (interval, value) in self.iter() { + seq.serialize_element(&(interval, value))?; } seq.end() } } -impl<'de, I, K, V> Deserialize<'de> for DiscreteRangeMap +impl<'de, I, K, V> Deserialize<'de> for NoditMap where I: PointType, - K: RangeType + Deserialize<'de>, + K: IntervalType + Deserialize<'de>, V: Deserialize<'de>, { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { - deserializer.deserialize_seq(DiscreteRangeMapVisitor { + deserializer.deserialize_seq(NoditMapVisitor { i: PhantomData, k: PhantomData, v: PhantomData, @@ -1738,32 +1738,32 @@ where } } -struct DiscreteRangeMapVisitor { +struct NoditMapVisitor { i: PhantomData, k: PhantomData, v: PhantomData, } -impl<'de, I, K, V> Visitor<'de> for DiscreteRangeMapVisitor +impl<'de, I, K, V> Visitor<'de> for NoditMapVisitor where I: PointType, - K: RangeType + Deserialize<'de>, + K: IntervalType + Deserialize<'de>, V: Deserialize<'de>, { - type Value = DiscreteRangeMap; + type Value = NoditMap; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("a DiscreteRangeMap") + formatter.write_str("a NoditMap") } fn visit_seq(self, mut access: A) -> Result where A: SeqAccess<'de>, { - let mut map = DiscreteRangeMap::new(); - while let Some((range_bounds, value)) = access.next_element()? { - map.insert_strict(range_bounds, value) - .map_err(|_| serde::de::Error::custom("ranges overlap"))?; + let mut map = NoditMap::new(); + while let Some((interval, value)) = access.next_element()? { + map.insert_strict(interval, value) + .map_err(|_| serde::de::Error::custom("intervals overlap"))?; } Ok(map) } @@ -1774,7 +1774,7 @@ mod tests { use pretty_assertions::assert_eq; use super::*; - use crate::inclusive_interval::{ee, ei, ie, ii, iu, ue, ui, uu}; + use crate::interval::{ee, ei, ie, ii, iu, ue, ui, uu}; use crate::utils::{config, contains_point, Config, CutResult}; //only every other number to allow mathematical_overlapping_definition @@ -1784,8 +1784,8 @@ mod tests { pub(crate) const NUMBERS_DOMAIN: &[i8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]; - fn basic() -> DiscreteRangeMap, bool> { - DiscreteRangeMap::from_slice_strict([ + fn basic() -> NoditMap, bool> { + NoditMap::from_slice_strict([ (ui(4), false), (ee(5, 7), true), (ii(7, 7), false), @@ -1793,7 +1793,7 @@ mod tests { ]) .unwrap() } - fn basic_slice() -> [(InclusiveInterval, bool); 4] { + fn basic_slice() -> [(Interval, bool); 4] { [ (ui(4), false), (ee(5, 7), true), @@ -1836,70 +1836,70 @@ mod tests { ); } fn assert_insert_strict( - mut before: DiscreteRangeMap, bool>, - to_insert: (InclusiveInterval, bool), + mut before: NoditMap, bool>, + to_insert: (Interval, bool), result: Result<(), OverlapError>, - after: [(InclusiveInterval, bool); N], + after: [(Interval, bool); N], ) { assert_eq!(before.insert_strict(to_insert.0, to_insert.1), result); - assert_eq!(before, DiscreteRangeMap::from_slice_strict(after).unwrap()) + assert_eq!(before, NoditMap::from_slice_strict(after).unwrap()) } #[test] fn overlapping_tests() { //case zero - for overlap_range in all_valid_test_bounds() { + for overlap_interval in all_valid_test_bounds() { //you can't overlap nothing assert!( - DiscreteRangeMap::, ()>::new() - .overlapping(overlap_range) + NoditMap::, ()>::new() + .overlapping(overlap_interval) .next() .is_none() ); } //case one - for overlap_range in all_valid_test_bounds() { - for inside_range in all_valid_test_bounds() { - let mut map = DiscreteRangeMap::new(); - map.insert_strict(inside_range, ()).unwrap(); + for overlap_interval in all_valid_test_bounds() { + for inside_interval in all_valid_test_bounds() { + let mut map = NoditMap::new(); + map.insert_strict(inside_interval, ()).unwrap(); let mut expected_overlapping = Vec::new(); - if overlaps(overlap_range, inside_range) { - expected_overlapping.push(inside_range); + if overlaps(overlap_interval, inside_interval) { + expected_overlapping.push(inside_interval); } let overlapping = map - .overlapping(overlap_range) + .overlapping(overlap_interval) .map(|(key, _)| key) .copied() .collect::>(); if overlapping != expected_overlapping { - dbg!(overlap_range, inside_range); + dbg!(overlap_interval, inside_interval); dbg!(overlapping, expected_overlapping); panic!( - "Discrepancy in .overlapping() with single inside range detected!" + "Discrepancy in .overlapping() with single inside interval detected!" ); } } } //case two - for overlap_range in all_valid_test_bounds() { - for (inside_range1, inside_range2) in + for overlap_interval in all_valid_test_bounds() { + for (inside_interval1, inside_interval2) in all_non_overlapping_test_bound_entries() { - let mut map = DiscreteRangeMap::new(); - map.insert_strict(inside_range1, ()).unwrap(); - map.insert_strict(inside_range2, ()).unwrap(); + let mut map = NoditMap::new(); + map.insert_strict(inside_interval1, ()).unwrap(); + map.insert_strict(inside_interval2, ()).unwrap(); let mut expected_overlapping = Vec::new(); - if overlaps(overlap_range, inside_range1) { - expected_overlapping.push(inside_range1); + if overlaps(overlap_interval, inside_interval1) { + expected_overlapping.push(inside_interval1); } - if overlaps(overlap_range, inside_range2) { - expected_overlapping.push(inside_range2); + if overlaps(overlap_interval, inside_interval2) { + expected_overlapping.push(inside_interval2); } //make our expected_overlapping the correct order if expected_overlapping.len() > 1 @@ -1910,16 +1910,16 @@ mod tests { } let overlapping = map - .overlapping(overlap_range) + .overlapping(overlap_interval) .map(|(key, _)| key) .copied() .collect::>(); if overlapping != expected_overlapping { - dbg!(overlap_range, inside_range1, inside_range2); + dbg!(overlap_interval, inside_interval1, inside_interval2); dbg!(overlapping, expected_overlapping); panic!( - "Discrepancy in .overlapping() with two inside ranges detected!" + "Discrepancy in .overlapping() with two inside intervals detected!" ); } } @@ -1954,16 +1954,16 @@ mod tests { ); } fn assert_remove_overlapping( - mut before: DiscreteRangeMap, bool>, - to_remove: InclusiveInterval, - result: [(InclusiveInterval, bool); N], - after: [(InclusiveInterval, bool); Y], + mut before: NoditMap, bool>, + to_remove: Interval, + result: [(Interval, bool); N], + after: [(Interval, bool); Y], ) { assert_eq!( before.remove_overlapping(to_remove).collect::>(), result ); - assert_eq!(before, DiscreteRangeMap::from_slice_strict(after).unwrap()) + assert_eq!(before, NoditMap::from_slice_strict(after).unwrap()) } #[test] @@ -2004,13 +2004,13 @@ mod tests { ); } fn assert_cut( - mut before: DiscreteRangeMap, bool>, - to_cut: InclusiveInterval, - result: [(InclusiveInterval, bool); Y], - after: [(InclusiveInterval, bool); N], + mut before: NoditMap, bool>, + to_cut: Interval, + result: [(Interval, bool); Y], + after: [(Interval, bool); N], ) { assert_eq!(before.cut(to_cut).collect::>(), result); - assert_eq!(before, DiscreteRangeMap::from_slice_strict(after).unwrap()); + assert_eq!(before, NoditMap::from_slice_strict(after).unwrap()); } #[test] @@ -2036,7 +2036,7 @@ mod tests { [ei(4, 5), ee(7, 14), ii(16, i8::MAX)], ); assert_eq!( - DiscreteRangeMap::from_slice_strict([( + NoditMap::from_slice_strict([( ii(i8::MIN, i8::MAX), false )]) @@ -2047,11 +2047,11 @@ mod tests { ); } fn assert_gaps_untrimmed( - map: DiscreteRangeMap, bool>, - range: InclusiveInterval, - result: [InclusiveInterval; N], + map: NoditMap, bool>, + interval: Interval, + result: [Interval; N], ) { - assert_eq!(map.gaps_untrimmed(range).collect::>(), result); + assert_eq!(map.gaps_untrimmed(interval).collect::>(), result); } #[test] @@ -2077,7 +2077,7 @@ mod tests { [ei(4, 5), ee(7, 14), ii(16, i8::MAX)], ); assert_eq!( - DiscreteRangeMap::from_slice_strict([( + NoditMap::from_slice_strict([( ii(i8::MIN, i8::MAX), false )]) @@ -2088,11 +2088,11 @@ mod tests { ); } fn assert_gaps_trimmed( - map: DiscreteRangeMap, bool>, - range: InclusiveInterval, - result: [InclusiveInterval; N], + map: NoditMap, bool>, + interval: Interval, + result: [Interval; N], ) { - assert_eq!(map.gaps_trimmed(range).collect::>(), result); + assert_eq!(map.gaps_trimmed(interval).collect::>(), result); } #[test] @@ -2138,16 +2138,16 @@ mod tests { ); } fn assert_insert_merge_touching( - mut before: DiscreteRangeMap, bool>, - to_insert: (InclusiveInterval, bool), - result: Result, OverlapError>, - after: [(InclusiveInterval, bool); N], + mut before: NoditMap, bool>, + to_insert: (Interval, bool), + result: Result, OverlapError>, + after: [(Interval, bool); N], ) { assert_eq!( before.insert_merge_touching(to_insert.0, to_insert.1), result ); - assert_eq!(before, DiscreteRangeMap::from_slice_strict(after).unwrap()) + assert_eq!(before, NoditMap::from_slice_strict(after).unwrap()) } #[test] fn insert_merge_touching_if_values_equal_tests() { @@ -2194,10 +2194,10 @@ mod tests { ); } fn assert_insert_merge_touching_if_values_equal( - mut before: DiscreteRangeMap, bool>, - to_insert: (InclusiveInterval, bool), - result: Result, OverlapError>, - after: [(InclusiveInterval, bool); N], + mut before: NoditMap, bool>, + to_insert: (Interval, bool), + result: Result, OverlapError>, + after: [(Interval, bool); N], ) { assert_eq!( before.insert_merge_touching_if_values_equal( @@ -2206,7 +2206,7 @@ mod tests { ), result ); - assert_eq!(before, DiscreteRangeMap::from_slice_strict(after).unwrap()) + assert_eq!(before, NoditMap::from_slice_strict(after).unwrap()) } #[test] @@ -2258,22 +2258,22 @@ mod tests { ); } fn assert_insert_merge_overlapping( - mut before: DiscreteRangeMap, bool>, - to_insert: (InclusiveInterval, bool), - result: InclusiveInterval, - after: [(InclusiveInterval, bool); N], + mut before: NoditMap, bool>, + to_insert: (Interval, bool), + result: Interval, + after: [(Interval, bool); N], ) { assert_eq!( before.insert_merge_overlapping(to_insert.0, to_insert.1), result ); - assert_eq!(before, DiscreteRangeMap::from_slice_strict(after).unwrap()) + assert_eq!(before, NoditMap::from_slice_strict(after).unwrap()) } #[test] fn insert_merge_touching_or_overlapping_tests() { assert_insert_merge_touching_or_overlapping( - DiscreteRangeMap::from_slice_strict([(ie(1, 4), false)]).unwrap(), + NoditMap::from_slice_strict([(ie(1, 4), false)]).unwrap(), (ie(0, 1), true), ie(0, 4), [(ie(0, 4), true)], @@ -2334,17 +2334,17 @@ mod tests { ); } fn assert_insert_merge_touching_or_overlapping( - mut before: DiscreteRangeMap, bool>, - to_insert: (InclusiveInterval, bool), - result: InclusiveInterval, - after: [(InclusiveInterval, bool); N], + mut before: NoditMap, bool>, + to_insert: (Interval, bool), + result: Interval, + after: [(Interval, bool); N], ) { assert_eq!( before .insert_merge_touching_or_overlapping(to_insert.0, to_insert.1), result ); - assert_eq!(before, DiscreteRangeMap::from_slice_strict(after).unwrap()) + assert_eq!(before, NoditMap::from_slice_strict(after).unwrap()) } #[test] @@ -2366,17 +2366,17 @@ mod tests { #[test] fn overlaps_tests() { - for range1 in all_valid_test_bounds() { - for range2 in all_valid_test_bounds() { - let our_answer = overlaps(range1, range2); + for interval1 in all_valid_test_bounds() { + for interval2 in all_valid_test_bounds() { + let our_answer = overlaps(interval1, interval2); let mathematical_definition_of_overlap = NUMBERS_DOMAIN.iter().any(|x| { - contains_point(range1, *x) && contains_point(range2, *x) + contains_point(interval1, *x) && contains_point(interval2, *x) }); if our_answer != mathematical_definition_of_overlap { - dbg!(range1, range2); + dbg!(interval1, interval2); dbg!(mathematical_definition_of_overlap, our_answer); panic!("Discrepancy in overlaps() detected!"); } @@ -2385,14 +2385,14 @@ mod tests { } #[test] - fn cut_range_tests() { + fn cut_interval_tests() { for base in all_valid_test_bounds() { for cut in all_valid_test_bounds() { let cut_result @ CutResult { before_cut: b, inside_cut: i, after_cut: a, - } = cut_range(base, cut); + } = cut_interval(base, cut); let mut on_left = true; @@ -2435,15 +2435,15 @@ mod tests { } } } - fn con(x: Option>, point: &i8) -> bool { + fn con(x: Option>, point: &i8) -> bool { match x { Some(y) => contains_point(y, *point), None => false, } } #[test] - fn cut_range_bounds_should_return_valid_ranges() { - let result: CutResult = cut_range(ie(3, 8), ie(5, 8)); + fn cut_interval_should_return_valid_intervals() { + let result: CutResult = cut_interval(ie(3, 8), ie(5, 8)); if let Some(x) = result.before_cut { assert!(x.is_valid()); } @@ -2454,7 +2454,7 @@ mod tests { assert!(x.is_valid()); } - let result = cut_range(ie(3, 8), ie(3, 5)); + let result = cut_interval(ie(3, 8), ie(3, 5)); if let Some(x) = result.before_cut { assert!(x.is_valid()); } @@ -2468,38 +2468,38 @@ mod tests { #[test] fn test_intersection() { - let input = InclusiveInterval { start: 5, end: 10 }; + let input = Interval { start: 5, end: 10 }; assert_eq!( - input.intersect(&InclusiveInterval { start: 8, end: 13 }), - Some(InclusiveInterval { start: 8, end: 10 }) + input.intersect(&Interval { start: 8, end: 13 }), + Some(Interval { start: 8, end: 10 }) ); assert_eq!( - input.intersect(&InclusiveInterval { start: 10, end: 13 }), - Some(InclusiveInterval { start: 10, end: 10 }) + input.intersect(&Interval { start: 10, end: 13 }), + Some(Interval { start: 10, end: 10 }) ); assert_eq!( - input.intersect(&InclusiveInterval { start: 11, end: 13 }), + input.intersect(&Interval { start: 11, end: 13 }), None ); } #[test] fn test_translate() { - let input = InclusiveInterval { start: 5, end: 10 }; - assert_eq!(input.translate(3), InclusiveInterval { start: 8, end: 13 }); - assert_eq!(input.translate(-2), InclusiveInterval { start: 3, end: 8 }); + let input = Interval { start: 5, end: 10 }; + assert_eq!(input.translate(3), Interval { start: 8, end: 13 }); + assert_eq!(input.translate(-2), Interval { start: 3, end: 8 }); } #[test] fn test_size() { - assert_eq!(InclusiveInterval { start: 5, end: 10 }.size(), 6); - assert_eq!(InclusiveInterval { start: 6, end: 6 }.size(), 1); + assert_eq!(Interval { start: 5, end: 10 }.size(), 6); + assert_eq!(Interval { start: 6, end: 6 }.size(), 1); } // Test Helper Functions //====================== fn all_non_overlapping_test_bound_entries() - -> Vec<(InclusiveInterval, InclusiveInterval)> { + -> Vec<(Interval, Interval)> { let mut output = Vec::new(); for test_bounds1 in all_valid_test_bounds() { for test_bounds2 in all_valid_test_bounds() { @@ -2512,12 +2512,12 @@ mod tests { return output; } - fn all_valid_test_bounds() -> Vec> { + fn all_valid_test_bounds() -> Vec> { let mut output = Vec::new(); for i in NUMBERS { for j in NUMBERS { if i <= j { - output.push(InclusiveInterval { start: *i, end: *j }); + output.push(Interval { start: *i, end: *j }); } } } diff --git a/src/set.rs b/src/set.rs new file mode 100644 index 0000000..139f83a --- /dev/null +++ b/src/set.rs @@ -0,0 +1,306 @@ +/* +Copyright 2022,2023 James Forster + +This file is part of nodit. + +nodit 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. + +nodit 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 nodit. If not, see . +*/ + +//! A module containing [`NoditSet`] and related types. +//! +//! Since [`NoditSet`] is just a wrapper around +//! [`NoditMap`], most of the methods' docs will point towards the +//! equivalent method's docs on [`NoditMap`] to prevent +//! inconsistency. + +use core::fmt; +use core::marker::PhantomData; + +use serde::de::{SeqAccess, Visitor}; +use serde::ser::SerializeSeq; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +use crate::map::IntoIter as NoditMapIntoIter; +use crate::{NoditMap, OverlapError, PointType, IntervalType}; + +/// An ordered set of non-overlapping intervals based on [`NoditMap`]. +/// +/// `I` is the generic type parameter for the [`Ord`] type the `K` +/// type is interval over. +/// +/// `K` is the generic type parameter for the interval implementing type +/// in the set. +/// +/// Phrasing it another way: `I` is the point type and `K` is the interval type. +/// +/// See [`NoditMap`] for more details. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct NoditSet { + inner: NoditMap, +} + +impl NoditSet +where + I: PointType, + K: IntervalType, +{ + /// See [`NoditMap::overlaps()`] for more details. + pub fn overlaps(&self, interval: Q) -> bool + where + Q: IntervalType, + { + self.inner.overlaps(interval) + } + /// See [`NoditMap::overlapping()`] for more details. + pub fn overlapping( + &self, + interval: Q, + ) -> impl DoubleEndedIterator + where + Q: IntervalType, + { + self.inner.overlapping(interval).map(first) + } + /// See [`NoditMap::get_entry_at_point()`] for more details. + pub fn get_at_point(&self, point: I) -> Result<&K, K> { + self.inner.get_entry_at_point(point).map(first) + } + /// See [`NoditMap::contains_point()`] for more details. + pub fn contains_point(&self, point: I) -> bool { + self.inner.contains_point(point) + } + /// See [`NoditMap::remove_overlapping()`] for more details. + pub fn remove_overlapping<'a, Q>( + &'a mut self, + interval: Q, + ) -> impl Iterator + where + Q: IntervalType + 'a, + { + self.inner.remove_overlapping(interval).map(first) + } + /// See [`NoditMap::cut()`] for more details. + pub fn cut<'a, Q>(&'a mut self, interval: Q) -> impl Iterator + where + Q: IntervalType + 'a, + { + self.inner.cut(interval).map(first) + } + /// See [`NoditMap::gaps_untrimmed()`] for more details. + pub fn gaps_untrimmed<'a, Q>( + &'a self, + interval: Q, + ) -> impl Iterator + '_ + where + Q: IntervalType + 'a, + { + self.inner.gaps_untrimmed(interval) + } + /// See [`NoditMap::gaps_trimmed()`] for more details. + pub fn gaps_trimmed<'a, Q>( + &'a self, + interval: Q, + ) -> impl Iterator + '_ + where + Q: IntervalType + 'a, + { + self.inner.gaps_trimmed(interval) + } + /// See [`NoditMap::contains_entire_interval()`] for more details. + pub fn contains_entire_interval(&self, interval: Q) -> bool + where + Q: IntervalType, + { + self.inner.contains_entire_interval(interval) + } + /// See [`NoditMap::insert_strict()`] for more details. + pub fn insert_strict(&mut self, interval: K) -> Result<(), OverlapError<()>> { + self.inner.insert_strict(interval, ()) + } + /// See [`NoditMap::insert_merge_touching()`] for more details. + pub fn insert_merge_touching( + &mut self, + interval: K, + ) -> Result> { + self.inner.insert_merge_touching(interval, ()) + } + /// See [`NoditMap::insert_merge_overlapping()`] for more details. + pub fn insert_merge_overlapping(&mut self, interval: K) -> K { + self.inner.insert_merge_overlapping(interval, ()) + } + /// See [`NoditMap::insert_merge_touching_or_overlapping()`] for more details. + pub fn insert_merge_touching_or_overlapping(&mut self, interval: K) -> K { + self.inner.insert_merge_touching_or_overlapping(interval, ()) + } + /// See [`NoditMap::insert_overwrite()`] for more details. + pub fn insert_overwrite(&mut self, interval: K) -> impl Iterator { + self.inner.insert_overwrite(interval, ()).map(first) + } + /// See [`NoditMap::from_slice_strict()`] for more details. + pub fn from_slice_strict( + slice: [K; N], + ) -> Result, OverlapError<()>> { + let mut set = NoditSet::new(); + for interval in slice { + set.insert_strict(interval)?; + } + return Ok(set); + } + /// See [`NoditMap::from_iter_strict()`] for more details. + pub fn from_iter_strict( + iter: impl Iterator, + ) -> Result, OverlapError<()>> { + let mut set = NoditSet::new(); + for interval in iter { + set.insert_strict(interval)?; + } + return Ok(set); + } +} + +impl NoditSet { + /// See [`NoditMap::new()`] for more details. + pub fn new() -> Self { + NoditSet { + inner: NoditMap::new(), + } + } + /// See [`NoditMap::len()`] for more details. + pub fn len(&self) -> usize { + self.inner.len() + } + /// See [`NoditMap::is_empty()`] for more details. + pub fn is_empty(&self) -> bool { + self.inner.is_empty() + } + /// See [`NoditMap::iter()`] for more details. + pub fn iter(&self) -> impl DoubleEndedIterator { + self.inner.iter().map(first) + } + /// See [`NoditMap::first_entry()`] for more details. + pub fn first(&self) -> Option<&K> { + self.inner.first_entry().map(first) + } + /// See [`NoditMap::last_entry()`] for more details. + pub fn last(&self) -> Option<&K> { + self.inner.last_entry().map(first) + } +} + +// Helper Functions ========================== + +fn first((a, _): (A, B)) -> A { + a +} + +// Trait Impls ========================== + +impl IntoIterator for NoditSet { + type Item = K; + type IntoIter = IntoIter; + fn into_iter(self) -> Self::IntoIter { + return IntoIter { + inner: self.inner.into_iter(), + }; + } +} +/// An owning iterator over the entries of a [`NoditSet`]. +/// +/// This `struct` is created by the [`into_iter`] method on +/// [`NoditSet`] (provided by the [`IntoIterator`] trait). See +/// its documentation for more. +/// +/// [`into_iter`]: IntoIterator::into_iter +/// [`IntoIterator`]: core::iter::IntoIterator +pub struct IntoIter { + inner: NoditMapIntoIter, +} +impl Iterator for IntoIter { + type Item = K; + fn next(&mut self) -> Option { + self.inner.next().map(first) + } +} + +impl Default for NoditSet +where + I: PointType, +{ + fn default() -> Self { + NoditSet { + inner: NoditMap::default(), + } + } +} + +impl Serialize for NoditSet +where + K: Serialize, +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut seq = serializer.serialize_seq(Some(self.len()))?; + for interval in self.iter() { + seq.serialize_element(&interval)?; + } + seq.end() + } +} + +impl<'de, I, K> Deserialize<'de> for NoditSet +where + I: PointType, + K: IntervalType + Deserialize<'de>, +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_seq(NoditSetVisitor { + i: PhantomData, + k: PhantomData, + }) + } +} + +struct NoditSetVisitor { + i: PhantomData, + k: PhantomData, +} + +impl<'de, I, K> Visitor<'de> for NoditSetVisitor +where + I: PointType, + K: IntervalType + Deserialize<'de>, +{ + type Value = NoditSet; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a NoditSet") + } + + fn visit_seq(self, mut access: A) -> Result + where + A: SeqAccess<'de>, + { + let mut set = NoditSet::new(); + while let Some(interval) = access.next_element()? { + set.insert_strict(interval) + .map_err(|_| serde::de::Error::custom("intervals overlap"))?; + } + Ok(set) + } +} diff --git a/src/utils.rs b/src/utils.rs index 7ccbdb9..9652e25 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,34 +1,34 @@ /* Copyright 2022,2023 James Forster -This file is part of discrete_range_map. +This file is part of nodit. -discrete_range_map is free software: you can redistribute it and/or +nodit 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. -discrete_range_map is distributed in the hope that it will be useful, +nodit 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 discrete_range_map. If not, see . +along with nodit. If not, see . */ use core::cmp::Ordering; -use crate::{InclusiveInterval, InclusiveRange, PointType, RangeType}; +use crate::{Interval, InclusiveInterval, PointType, IntervalType}; -pub(crate) fn cmp_point_with_range(point: I, range: K) -> Ordering +pub(crate) fn cmp_point_with_interval(point: I, interval: K) -> Ordering where I: PointType, - K: RangeType, + K: IntervalType, { - if point < range.start() { + if point < interval.start() { Ordering::Less - } else if point > range.end() { + } else if point > interval.end() { Ordering::Greater } else { Ordering::Equal @@ -48,8 +48,8 @@ pub(crate) enum Config { pub(crate) fn config(a: A, b: B) -> Config where I: PointType, - A: RangeType, - B: RangeType, + A: IntervalType, + B: IntervalType, { if a.start() < b.start() { match (contains_point(a, b.start()), contains_point(a, b.end())) { @@ -69,21 +69,21 @@ where } enum SortedConfig { - NonOverlapping(InclusiveInterval, InclusiveInterval), - PartialOverlap(InclusiveInterval, InclusiveInterval), - Swallowed(InclusiveInterval, InclusiveInterval), + NonOverlapping(Interval, Interval), + PartialOverlap(Interval, Interval), + Swallowed(Interval, Interval), } fn sorted_config(a: A, b: B) -> SortedConfig where I: PointType, - A: RangeType, - B: RangeType, + A: IntervalType, + B: IntervalType, { - let ae = InclusiveInterval { + let ae = Interval { start: a.start(), end: a.end(), }; - let be = InclusiveInterval { + let be = Interval { start: b.start(), end: b.end(), }; @@ -102,25 +102,25 @@ where } } -pub(crate) fn contains_point(range: K, point: I) -> bool +pub(crate) fn contains_point(interval: K, point: I) -> bool where I: PointType, - K: RangeType, + K: IntervalType, { - cmp_point_with_range(point, range).is_eq() + cmp_point_with_interval(point, interval).is_eq() } #[derive(Debug)] pub(crate) struct CutResult { - pub(crate) before_cut: Option>, - pub(crate) inside_cut: Option>, - pub(crate) after_cut: Option>, + pub(crate) before_cut: Option>, + pub(crate) inside_cut: Option>, + pub(crate) after_cut: Option>, } -pub(crate) fn cut_range(base: A, cut: B) -> CutResult +pub(crate) fn cut_interval(base: A, cut: B) -> CutResult where I: PointType, - A: RangeType, - B: RangeType, + A: IntervalType, + B: IntervalType, { let mut result = CutResult { before_cut: None, @@ -130,34 +130,34 @@ where match config(base, cut) { Config::LeftFirstNonOverlapping => { - result.before_cut = Some(InclusiveInterval { + result.before_cut = Some(Interval { start: base.start(), end: base.end(), }); } Config::LeftFirstPartialOverlap => { - result.before_cut = Some(InclusiveInterval { + result.before_cut = Some(Interval { start: base.start(), end: cut.start().down().unwrap(), }); - result.inside_cut = Some(InclusiveInterval { + result.inside_cut = Some(Interval { start: cut.start(), end: base.end(), }); } Config::LeftContainsRight => { - result.before_cut = Some(InclusiveInterval { + result.before_cut = Some(Interval { start: base.start(), end: cut.start().down().unwrap(), }); - result.inside_cut = Some(InclusiveInterval { + result.inside_cut = Some(Interval { start: cut.start(), end: cut.end(), }); //if cut is already max then we don't need to have an //after_cut if let Some(upped_end) = cut.end().up() { - result.after_cut = Some(InclusiveInterval { + result.after_cut = Some(Interval { start: upped_end, end: base.end(), }); @@ -165,30 +165,30 @@ where } Config::RightFirstNonOverlapping => { - result.after_cut = Some(InclusiveInterval { + result.after_cut = Some(Interval { start: base.start(), end: base.end(), }); } Config::RightFirstPartialOverlap => { - result.after_cut = Some(InclusiveInterval { + result.after_cut = Some(Interval { start: cut.end().up().unwrap(), end: base.end(), }); - result.inside_cut = Some(InclusiveInterval { + result.inside_cut = Some(Interval { start: base.start(), end: cut.end(), }); } Config::RightContainsLeft => { - result.inside_cut = Some(InclusiveInterval { + result.inside_cut = Some(Interval { start: base.start(), end: base.end(), }); } } - //only return valid ranges + //only return valid intervals return CutResult { before_cut: result.before_cut.filter(|x| x.is_valid()), inside_cut: result.inside_cut.filter(|x| x.is_valid()), @@ -199,8 +199,8 @@ where pub(crate) fn overlaps(a: A, b: B) -> bool where I: PointType, - A: RangeType, - B: RangeType, + A: IntervalType, + B: IntervalType, { !matches!(sorted_config(a, b), SortedConfig::NonOverlapping(_, _)) } From 94e5bdc4b354c54171c47c5a0f838663f3c628b1 Mon Sep 17 00:00:00 2001 From: ripytide Date: Tue, 2 Jan 2024 19:34:05 +0000 Subject: [PATCH 2/2] updated the changelog and readme --- CHANGELOG.md | 3 +++ Cargo.toml | 5 ++--- README.md | 19 ++++++++++++++----- src/lib.rs | 17 +++++++---------- 4 files changed, 26 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ceb5736..3f0b4bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Renamed `gaps()` to `gaps_trimmed()` and added a `gaps_untrimmed()` method - Mass replaced renamed from the word "range" to the word "interval" all code items, docs. +- The crate has been renamed from `discrete_range_map` to `nodit` +- The `DiscreteRangeMap` is now `NoditMap` and the `DiscreteRangeSet` is now + `NoditSet` ### Fixed diff --git a/Cargo.toml b/Cargo.toml index 6ebbb04..4c1e8ac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,9 +4,8 @@ version = "0.6.2" authors = ["James Forster "] edition = "2021" description = """ -This crate provides NoditMap and NoditSet, Data -Structures for storing Non-Overlapping Discrete Intervals based off -BTreeMap. +This crate provides NoditMap and NoditSet, Non-Overlapping Discrete +Interval Tree data-structures, which are based off BTreeMap. """ documentation = "https://docs.rs/nodit" readme = "README.md" diff --git a/README.md b/README.md index fa0c1cc..5afc397 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,8 @@ nodit_logo

-This crate provides [`NoditMap`] and [`NoditSet`], Data Structures for storing -non-overlapping discrete intervals based off [`BTreeMap`]. +This crate provides [`NoditMap`] and [`NoditSet`], Non-Overlapping Discrete +Interval Tree data-structures, which are based off [`BTreeMap`]. `no_std` is supported and should work with the default features. @@ -296,11 +296,20 @@ Lots of my inspiration came from the [`rangemap`] crate. The BTreeMap implementation ([`btree_monstrousity`]) used under the hood was inspired and forked from the [`copse`] crate. -## Name Change - -This crate was previously named [`range_bounds_map`] it was renamed +## Name Changes +This crate was later named [`range_bounds_map`] it was renamed around about 2023-04-24 due to it no longer being an accurate name. +This crate was previously named [`range_bounds_map`] it was renamed to +[`discrete_range_map`] around about 2023-04-24 due to the old name no longer +being very accurate. + +This crate was then renamed again on 2023-01-02 from [`discrete_range_map`] to +[`nodit`] due to a change to prefer the word "interval" over "range" whenever +possible for consistency. Hopefully, even if the library undergoes more changes +the shorter and more abstract name may be able to be kept even if it loses its +acronym of Non-Overlapping Discrete Interval Tree. + ## Similar Crates Here are some relevant crates I found whilst searching around the diff --git a/src/lib.rs b/src/lib.rs index 257ad29..bb05614 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,9 +17,8 @@ You should have received a copy of the GNU Affero General Public License along with nodit. If not, see . */ -//! This crate provides [`NoditMap`] and [`NoditSet`], -//! Data Structures for storing non-overlapping discrete intervals based -//! off [`BTreeMap`]. +//! This crate provides [`NoditMap`] and [`NoditSet`], Non-Overlapping Discrete +//! Interval Tree data-structures, which are based off [`BTreeMap`]. //! //! `no_std` is supported and should work with the default features. //! @@ -55,8 +54,7 @@ along with nodit. If not, see . //! //! use nodit::interval::ie; //! use nodit::{ -//! DiscreteFinite, NoditMap, InclusiveInterval, -//! Interval, +//! DiscreteFinite, InclusiveInterval, Interval, NoditMap, //! }; //! //! #[derive(Debug, Copy, Clone)] @@ -236,7 +234,7 @@ along with nodit. If not, see . //! // returned by `get_entry_at_point()`, for example: //! //! use nodit::interval::uu; -//! use nodit::{NoditMap, Interval}; +//! use nodit::{Interval, NoditMap}; //! //! let map: NoditMap< //! WithInfinity, @@ -382,14 +380,13 @@ extern crate alloc; pub(crate) mod utils; pub mod discrete_finite; +pub mod interval; pub mod map; pub mod set; -pub mod interval; pub use crate::discrete_finite::DiscreteFinite; +pub use crate::interval::Interval; pub use crate::map::{ - NoditMap, InclusiveInterval, IntervalType, OverlapError, - PointType, + InclusiveInterval, IntervalType, NoditMap, OverlapError, PointType, }; pub use crate::set::NoditSet; -pub use crate::interval::Interval;