diff --git a/Cargo.lock b/Cargo.lock index a2d867a..01eedc4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -118,18 +118,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.148" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e53f64bb4ba0191d6d0676e1b141ca55047d83b74f5607e6d8eb88126c52c2dc" +checksum = "e326c9ec8042f1b5da33252c8a37e9ffbd2c9bef0155215b6e6c80c790e05f91" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.148" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a55492425aa53521babf6137309e7d34c20bbfbbfcfe2c7f3a047fd1f6b92c0c" +checksum = "42a3df25b0713732468deadad63ab9da1f1fd75a48a15024b50363f128db627e" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 4c82c74..90dbb7c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,20 +6,17 @@ edition = "2021" description = """ This crate provides `RangeBoundsMap` and `RangeBoundsSet`. -`RangeBoundsMap` is similar to `BTreeMap` except `RangeBoundsMap` -uses any type that implements the `RangeBounds` trait as keys, while -maintaining two invariants: -- No two keys may overlap -- A keys' `start_bound()` <= its `end_bound()` +`RangeBoundsMap` is an ordered map of non-overlapping [`RangeBounds`] +based on [`BTreeMap`]. -`RangeBoundsSet` is like `RangeBoundsMap` except it -uses `()` as values, as `BTreeSet` does for `BTreeMap` +`RangeBoundsSet` is an ordered set of non-overlapping [`RangeBounds`] +based on [`RangeBoundsMap`]. """ documentation = "https://docs.rs/range_bounds_map" readme = "README.md" homepage = "https://github.com/ripytide/range_bounds_map" repository = "https://github.com/ripytide/range_bounds_map" -license = "GPL-3.0-or-later" +license = "AGPL-3.0-or-later" keywords = ["data-structures", "map", "data", "library"] categories = ["data-structures"] diff --git a/README.md b/README.md index 129e96d..f35f349 100644 --- a/README.md +++ b/README.md @@ -2,41 +2,19 @@ [![Crates.io](https://img.shields.io/crates/v/range_bounds_set)](https://crates.io/crates/range_bounds_set) [![Docs](https://docs.rs/range_bounds_set/badge)](https://docs.rs/range_bounds_set) +[![Maintained]](https://img.shields.io/maintenance/yes/2023)

range_bounds_map_logo

-This crate provides [`RangeBoundsMap`] and [`RangeBoundsSet`]. +This crate provides [`RangeBoundsMap`] and [`RangeBoundsSet`.] -[`RangeBoundsMap`] is similar to [`BTreeMap`] except [`RangeBoundsMap`] -uses any type that implements the [`RangeBounds`] trait as keys, while -maintaining two invariants: +[`RangeBoundsMap`] is an ordered map of non-overlapping [`RangeBounds`] +based on [`BTreeMap`]. -- No two keys may overlap -- A keys' [`start_bound()`] <= its [`end_bound()`] - -[`RangeBoundsSet`] is like [`RangeBoundsMap`] except it -uses `()` as values, as [`BTreeSet`] does for [`BTreeMap`] - -## Key Definitions: - -### Overlap - -Two `RangeBounds` are "overlapping" if there exists a point that is -contained within both `RangeBounds`. - -### Touching - -Two `RangeBounds` 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`. - -### Coalesce - -When a `RangeBounds` "coalesces" other `RangeBounds` it absorbs them -to become larger. +[`RangeBoundsSet`] is an ordered set of non-overlapping [`RangeBounds`] +based on [`RangeBoundsMap`]. ## Example using [`Range`]s @@ -45,8 +23,8 @@ use range_bounds_map::RangeBoundsMap; let mut range_bounds_map = RangeBoundsMap::new(); -range_bounds_map.insert(0..5, true); -range_bounds_map.insert(5..10, false); +range_bounds_map.insert_platonic(0..5, true); +range_bounds_map.insert_platonic(5..10, false); assert_eq!(range_bounds_map.overlaps(&(-2..12)), true); assert_eq!(range_bounds_map.contains_point(&20), false); @@ -112,54 +90,51 @@ assert_eq!( ); ``` -# How +## Key Definitions: -Most of the [`RangeBounds`]-specific methods on [`RangeBoundsMap`] -utilize the [`RangeBoundsMap::overlapping()`] method which -internally uses [`BTreeMap`]'s [`range()`] function. To allow -using [`range()`] for this purpose a newtype wrapper is wrapped -around the [`start_bound()`]s so that we can apply our custom [`Ord`] -implementation onto all the [`start_bound()`]s. +### Overlap + +Two `RangeBounds` are "overlapping" if there exists a point that is +contained within both `RangeBounds`. + +### Touching + +Two `RangeBounds` 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`. + +### Coalesce + +When a `RangeBounds` "coalesces" other `RangeBounds` it absorbs them +to become larger. # Improvements/Caveats -There are a few issues I can think of with this implementation, -each of them are documented as GitHub Issues. If you would like -any of these features added, drop a comment in a respective GitHub -Issue (or even open a new one) and I'd be happy to implement it. - -To summarise: - -- Some overly strict Trait-Bounds on some functions due to `impl` - level `Trait-Bounds` rather than specific `function` level - `Trait-Bounds` - Missing some functions common to BTreeMap and BTreeSet like: - `clear()` - `is_subset()` - etc... prob a bunch more -- Sub-optimal use of unnecessary `cloned()` just to placate the borrow checker -- Lot's of optimisations available +- Not particularly optimized, (which doesn't mean it's neccessarily slow) - Can't use TryFrom<(Bound, Bound)> instead of [`TryFromBounds`] (relys on - upstream to impl) -- The data structures are lacking a lot of useful traits, such as: - - FromIterator - - IntoIterator - - Prob a bunch more + upstream to impl, see [this thread](https://internals.rust-lang.org/t/range-should-impl-tryfrom-bound-bound)) # Credit -I originally came up with the `StartBound`: [`Ord`] bodge on my -own, however, I later stumbled across [`rangemap`] which also used -a `StartBound`: [`Ord`] bodge. [`rangemap`] then became my main -source of inspiration. The aim for my library was to become a more -generic superset of [`rangemap`], following from -[this issue](https://github.com/jeffparsons/rangemap/issues/56) and -[this pull request](https://github.com/jeffparsons/rangemap/pull/57) -in which I changed [`rangemap`]'s [`RangeMap`] to use -[`RangeBounds`]s as keys before I realized it might be easier and -simpler to just write it all from scratch. Which ended up working -really well with some simplifications I made which ended up -resulting in much less code (~600 lines over [`rangemap`]'s ~2700) +I originally came up with the `StartBound`: [`Ord`] bodge on my own, +however, I later stumbled across [`rangemap`] which also used a +`StartBound`: [`Ord`] bodge. [`rangemap`] then became my main source +of inspiration. + +The aim for my library was to become a more generic +superset of [`rangemap`], following from [this +issue](https://github.com/jeffparsons/rangemap/issues/56) and [this +pull request](https://github.com/jeffparsons/rangemap/pull/57) in +which I changed [`rangemap`]'s [`RangeMap`] to use [`RangeBounds`]s as +keys before I realized it might be easier and simpler to just write it +all from scratch. Which ended up working really well with some +simplifications (BoundOrd) I made which made some of the code much +easier to work with. # Similar Crates diff --git a/src/bound_ord.rs b/src/bound_ord.rs index ab878a1..2fcf85c 100644 --- a/src/bound_ord.rs +++ b/src/bound_ord.rs @@ -4,16 +4,16 @@ Copyright 2022 James Forster This file is part of range_bounds_map. range_bounds_map is free software: you can redistribute it and/or -modify it under the terms of the GNU General Public License as +modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. range_bounds_map is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. +Affero General Public License for more details. -You should have received a copy of the GNU General Public License +You should have received a copy of the GNU Affero General Public License along with range_bounds_map. If not, see . */ @@ -51,6 +51,7 @@ pub(crate) enum BoundOrd { } impl BoundOrd { + #[trivial] pub(crate) fn start(bound: Bound) -> Self { match bound { Bound::Included(point) => BoundOrd::Included(point), @@ -58,6 +59,7 @@ impl BoundOrd { Bound::Unbounded => BoundOrd::StartUnbounded, } } + #[trivial] pub(crate) fn end(bound: Bound) -> Self { match bound { Bound::Included(point) => BoundOrd::Included(point), diff --git a/src/lib.rs b/src/lib.rs index 707760a..e896039 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,20 +4,194 @@ Copyright 2022 James Forster This file is part of range_bounds_map. range_bounds_map is free software: you can redistribute it and/or -modify it under the terms of the GNU General Public License as +modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. range_bounds_map is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. +Affero General Public License for more details. -You should have received a copy of the GNU General Public License +You should have received a copy of the GNU Affero General Public License along with range_bounds_map. If not, see . */ -//! todo +//! This crate provides [`RangeBoundsMap`] and [`RangeBoundsSet`]. +//! +//! [`RangeBoundsMap`] is an ordered map of non-overlapping [`RangeBounds`] +//! based on [`BTreeMap`]. +//! +//! [`RangeBoundsSet`] is an ordered set of non-overlapping [`RangeBounds`] +//! based on [`RangeBoundsMap`]. +//! +//! ## Example using [`Range`]s +//! +//! ```rust +//! use range_bounds_map::RangeBoundsMap; +//! +//! let mut range_bounds_map = RangeBoundsMap::new(); +//! +//! range_bounds_map.insert_platonic(0..5, true); +//! range_bounds_map.insert_platonic(5..10, false); +//! +//! assert_eq!(range_bounds_map.overlaps(&(-2..12)), true); +//! assert_eq!(range_bounds_map.contains_point(&20), false); +//! assert_eq!(range_bounds_map.contains_point(&5), true); +//! ``` +//! +//! ## Example using a custom [`RangeBounds`] type +//! +//! ```rust +//! use std::ops::{Bound, RangeBounds}; +//! +//! use range_bounds_map::RangeBoundsMap; +//! +//! #[derive(Debug)] +//! enum Reservation { +//! // Start, End (Inclusive-Inclusive) +//! Finite(u8, u8), +//! // Start (Exclusive) +//! Infinite(u8), +//! } +//! +//! // First, we need to implement RangeBounds +//! impl RangeBounds for Reservation { +//! fn start_bound(&self) -> Bound<&u8> { +//! match self { +//! Reservation::Finite(start, _) => { +//! Bound::Included(start) +//! } +//! Reservation::Infinite(start) => { +//! Bound::Excluded(start) +//! } +//! } +//! } +//! fn end_bound(&self) -> Bound<&u8> { +//! match self { +//! Reservation::Finite(_, end) => Bound::Included(end), +//! Reservation::Infinite(_) => Bound::Unbounded, +//! } +//! } +//! } +//! +//! // Next we can create a custom typed RangeBoundsMap +//! let reservation_map = RangeBoundsMap::try_from([ +//! (Reservation::Finite(10, 20), "Ferris".to_string()), +//! (Reservation::Infinite(20), "Corro".to_string()), +//! ]) +//! .unwrap(); +//! +//! for (reservation, name) in reservation_map.overlapping(&(16..17)) +//! { +//! println!( +//! "{name} has reserved {reservation:?} inside the range 16..17" +//! ); +//! } +//! +//! for (reservation, name) in reservation_map.iter() { +//! println!("{name} has reserved {reservation:?}"); +//! } +//! +//! assert_eq!( +//! reservation_map.overlaps(&Reservation::Infinite(0)), +//! true +//! ); +//! ``` +//! +//! ## Key Definitions: +//! +//! ### Overlap +//! +//! Two `RangeBounds` are "overlapping" if there exists a point that is +//! contained within both `RangeBounds`. +//! +//! ### Touching +//! +//! Two `RangeBounds` 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`. +//! +//! ### Coalesce +//! +//! When a `RangeBounds` "coalesces" other `RangeBounds` it absorbs them +//! to become larger. +//! +//! # How +//! +//! Most of the [`RangeBounds`]-specific methods on [`RangeBoundsMap`] +//! utilize the [`RangeBoundsMap::overlapping()`] method which +//! internally uses [`BTreeMap`]'s [`range()`] function. To allow +//! using [`range()`] for this purpose a newtype wrapper is wrapped +//! around the [`start_bound()`]s so that we can apply our custom [`Ord`] +//! implementation onto all the [`start_bound()`]s. +//! +//! # Improvements/Caveats +//! +//! - Missing some functions common to BTreeMap and BTreeSet like: +//! - `clear()` +//! - `is_subset()` +//! - etc... prob a bunch more +//! - Not particularly optimized, (which doesn't mean it's neccessarily slow) +//! - Can't use TryFrom<(Bound, Bound)> instead of [`TryFromBounds`] (relys on +//! upstream to impl, see [this thread](https://internals.rust-lang.org/t/range-should-impl-tryfrom-bound-bound)) +//! +//! # Credit +//! +//! I originally came up with the `StartBound`: [`Ord`] bodge on my own, +//! however, I later stumbled across [`rangemap`] which also used a +//! `StartBound`: [`Ord`] bodge. [`rangemap`] then became my main source +//! of inspiration. The aim for my library was to become a more generic +//! superset of [`rangemap`], following from [this +//! issue](https://github.com/jeffparsons/rangemap/issues/56) and [this +//! pull request](https://github.com/jeffparsons/rangemap/pull/57) in +//! which I changed [`rangemap`]'s [`RangeMap`] to use [`RangeBounds`]s as +//! keys before I realized it might be easier and simpler to just write it +//! all from scratch. Which ended up working really well with some +//! simplifications (BoundOrd) I made which made some of the code much +//! easier to work with. +//! +//! # Similar Crates +//! +//! Here are some relevant crates I found whilst searching around the +//! topic area: +//! +//! - +//! Very similar to this crate but can only use [`Range`]s and +//! [`RangeInclusive`]s as keys in it's `map` and `set` structs (separately). +//! - +//! Cool library for fully-generic ranges (unlike std::ops ranges), along +//! with a `Ranges` datastructure for storing them (Vec-based +//! unfortunately) +//! - +//! Allows overlapping intervals but is immutable unfortunately +//! - +//! Very similar to rangemap except without a `gaps()` function and only +//! for [`Range`]s and not [`RangeInclusive`]s. And also no fancy coalescing +//! functions. +//! - +//! A data structure based off of a 2007 published paper! It supports any +//! RangeBounds as keys too, except it is implemented with a non-balancing +//! `Box` based tree, however it also supports overlapping +//! RangeBounds which my library does not. +//! - +//! I'm not entirely sure what this library is or isn't, but it looks like +//! a custom red-black tree/BTree implementation used specifically for a +//! Range Tree. Interesting but also quite old (5 years) and uses +//! unsafe. +//! +//! [`btreemap`]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html +//! [`btreeset`]: https://doc.rust-lang.org/std/collections/struct.BTreeSet.html +//! [`rangebounds`]: https://doc.rust-lang.org/std/ops/trait.RangeBounds.html +//! [`start_bound()`]: https://doc.rust-lang.org/std/ops/trait.RangeBounds.html#tymethod.start_bound +//! [`end_bound()`]: https://doc.rust-lang.org/std/ops/trait.RangeBounds.html#tymethod.end_bound +//! [`range`]: https://doc.rust-lang.org/std/ops/struct.Range.html +//! [`range()`]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html#method.range +//! [`rangemap`]: https://docs.rs/rangemap/latest/rangemap/ +//! [`rangeinclusivemap`]: https://docs.rs/rangemap/latest/rangemap/inclusive_map/struct.RangeInclusiveMap.html# +//! [`rangeinclusive`]: https://doc.rust-lang.org/std/ops/struct.RangeInclusive.html +//! [`ord`]: https://doc.rust-lang.org/std/cmp/trait.Ord.html #![feature(is_some_and)] #![feature(let_chains)] diff --git a/src/range_bounds_map.rs b/src/range_bounds_map.rs index c70e5bf..f186746 100644 --- a/src/range_bounds_map.rs +++ b/src/range_bounds_map.rs @@ -4,16 +4,16 @@ Copyright 2022 James Forster This file is part of range_bounds_map. range_bounds_map is free software: you can redistribute it and/or -modify it under the terms of the GNU General Public License as +modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. range_bounds_map is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. +Affero General Public License for more details. -You should have received a copy of the GNU General Public License +You should have received a copy of the GNU Affero General Public License along with range_bounds_map. If not, see . */ @@ -25,7 +25,7 @@ use std::ops::{Bound, RangeBounds}; use either::Either; use itertools::Itertools; -use labels::{tested, trivial}; +use labels::{parent_tested, tested, trivial}; use serde::{Deserialize, Serialize}; use crate::bound_ord::BoundOrd; @@ -131,8 +131,8 @@ where starts: BTreeMap, (K, V)>, } -/// An error type to represent a `RangeBounds` overlapping another -/// `RangeBounds` when it should not have. +/// An error type to represent a [`RangeBounds`] overlapping another +/// [`RangeBounds`] when it should not have. #[derive(PartialEq, Debug)] pub struct OverlapError; @@ -1112,6 +1112,7 @@ where return Ok(&self.starts.get(&BoundOrd::start(start_bound)).unwrap().0); } + #[parent_tested] fn touching_left(&self, range_bounds: &K) -> Option<&K> { return self .starts @@ -1125,6 +1126,7 @@ where .map(|x| &x.1.0) .filter(|x| touches(range_bounds, *x)); } + #[parent_tested] fn touching_right(&self, range_bounds: &K) -> Option<&K> { return self .starts @@ -1212,6 +1214,7 @@ where return Ok(&self.starts.get(&BoundOrd::start(start_bound)).unwrap().0); } + #[parent_tested] fn overlapping_swell<'a>( &'a self, range_bounds: &'a K, @@ -1467,7 +1470,7 @@ where }; } } -/// An owning iterator over the entries of a `RangeBoundsMap`. +/// An owning iterator over the entries of a [`RangeBoundsMap`]. /// /// This `struct` is created by the [`into_iter`] method on /// [`RangeBoundsMap`] (provided by the [`IntoIterator`] trait). See @@ -1480,6 +1483,7 @@ pub struct IntoIter { } impl Iterator for IntoIter { type Item = (K, V); + #[trivial] fn next(&mut self) -> Option { self.inner.next() } @@ -1674,7 +1678,6 @@ where !matches!(sorted_config(a, b), SortedConfig::NonOverlapping(_, _)) } -#[rustfmt::skip] #[tested] fn touches(a: &A, b: &B) -> bool where @@ -1683,13 +1686,15 @@ where I: PartialOrd, { match sorted_config(a, b) { - SortedConfig::NonOverlapping(a, b) => { - match (a.1, b.0) { - (Bound::Included(point1), Bound::Excluded(point2)) => point1 == point2, - (Bound::Excluded(point1), Bound::Included(point2)) => point1 == point2, - _ => false, + SortedConfig::NonOverlapping(a, b) => match (a.1, b.0) { + (Bound::Included(point1), Bound::Excluded(point2)) => { + point1 == point2 } - } + (Bound::Excluded(point1), Bound::Included(point2)) => { + point1 == point2 + } + _ => false, + }, _ => false, } } diff --git a/src/range_bounds_set.rs b/src/range_bounds_set.rs index 475711a..13ef144 100644 --- a/src/range_bounds_set.rs +++ b/src/range_bounds_set.rs @@ -4,23 +4,23 @@ Copyright 2022 James Forster This file is part of range_bounds_map. range_bounds_map is free software: you can redistribute it and/or -modify it under the terms of the GNU General Public License as +modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. range_bounds_map is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. +Affero General Public License for more details. -You should have received a copy of the GNU General Public License +You should have received a copy of the GNU Affero General Public License along with range_bounds_map. If not, see . */ use std::fmt::Debug; use std::ops::{Bound, RangeBounds}; -use labels::{tested, trivial}; +use labels::trivial; use serde::{Deserialize, Serialize}; use crate::range_bounds_map::IntoIter as MapIntoIter; @@ -191,7 +191,7 @@ where /// ); /// assert_eq!(range_bounds_set.len(), 1); /// ``` - #[tested] + #[trivial] pub fn insert_platonic( &mut self, range_bounds: K, @@ -241,7 +241,7 @@ where /// [(&(1..4)), (&(4..8))] /// ); /// ``` - #[tested] + #[trivial] pub fn overlapping( &self, range_bounds: &Q, @@ -331,7 +331,7 @@ where /// [&(8..100)] /// ); /// ``` - #[tested] + #[trivial] pub fn remove_overlapping( &mut self, range_bounds: &Q, @@ -375,7 +375,7 @@ where /// assert_eq!(base, after_cut); /// assert!(base.cut(&(60..=80)).is_err()); /// ``` - #[tested] + #[trivial] pub fn cut( &mut self, range_bounds: &Q, @@ -455,7 +455,7 @@ where /// ] /// ); /// ``` - #[tested] + #[trivial] pub fn gaps<'a, Q>( &'a self, outer_range_bounds: &'a Q, @@ -571,7 +571,7 @@ where /// [&(1..6), &(10..16)] /// ); /// ``` - #[tested] + #[trivial] pub fn insert_coalesce_touching( &mut self, range_bounds: K, @@ -622,7 +622,7 @@ where /// [&(-4..1), &(1..8), &(10..16)] /// ); /// ``` - #[tested] + #[trivial] pub fn insert_coalesce_overlapping( &mut self, range_bounds: K, @@ -676,7 +676,7 @@ where /// [&(-4..8), &(10..16)] /// ); /// ``` - #[tested] + #[trivial] pub fn insert_coalesce_touching_or_overlapping( &mut self, range_bounds: K, @@ -817,7 +817,7 @@ where }; } } -/// An owning iterator over the entries of a `RangeBoundsSet`. +/// An owning iterator over the entries of a [`RangeBoundsSet`]. /// /// This `struct` is created by the [`into_iter`] method on /// [`RangeBoundsSet`] (provided by the [`IntoIterator`] trait). See @@ -830,6 +830,7 @@ pub struct IntoIter { } impl Iterator for IntoIter { type Item = K; + #[trivial] fn next(&mut self) -> Option { self.inner.next().map(first) } @@ -847,6 +848,7 @@ where } } +#[trivial] fn first((a, _): (A, B)) -> A { a } diff --git a/src/try_from_bounds.rs b/src/try_from_bounds.rs index a48aa57..842f64a 100644 --- a/src/try_from_bounds.rs +++ b/src/try_from_bounds.rs @@ -4,16 +4,16 @@ Copyright 2022 James Forster This file is part of range_bounds_map. range_bounds_map is free software: you can redistribute it and/or -modify it under the terms of the GNU General Public License as +modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. range_bounds_map is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. +Affero General Public License for more details. -You should have received a copy of the GNU General Public License +You should have received a copy of the GNU Affero General Public License along with range_bounds_map. If not, see . */ diff --git a/todo.md b/todo.md index b598b42..7610c79 100644 --- a/todo.md +++ b/todo.md @@ -1,15 +1,18 @@ # refactor -- try to fix all the uses of cloned() in the library -- make a StartBoundWrapper that uses StartBound to implement ord and - use that instead of storing the startbound twice -- make a range_bounds configuration: NonOverlapping, A contained in B, - A partial overlap B, with A before B. And use it to simplify all the - logic based RangeBounds functions -- make an expand function to go RangeBounds -> (Bound, Bound) rather - than doing it manually everywhere +- try to remove unnecessary uses of cloned() +- use expand, expand_cloned and cloned_bounds everywhere +- replace instances of |(key, \_)| with fn first() - rename overwrite to insert_forceful -- replace instances of |(key, _)| with fn first() +- make all iterators cutsom types as is standardised in libraries for + some reason(?) +- take a look around idiomatic rust for a bit +- review method parameter names for all public functions + +# optimisations + +- make a StartBoundWrapper that uses BoundOrd to implement ord and + use that instead of storing the startbound twice # Documentation @@ -19,38 +22,19 @@ # features - make specifc RangeMap, RangeSet, RangeInclusiveMap... types for signature - simplification -- alternatively add just the one generic SafeRangeBoundsMap + Set that + simplification - alternatively add just the one generic SafeRangeBoundsMap + Set that just add unwraps everywhere to simplify signatures on known-"Safe" symmetric types such as Range +- add rangemap's insert function to finally make range_bounds_map a superset of rangemap -- make gaps() DoubleEndedIterator -- make all iterators cutsom types as is standardised in libraries for - some reason +- add append() split_off() etc.. -- add coalesce if same-value otherwise overwrite) function to make - finally make range_bounds_map a superset of rangemap +# open questions -# time based +- should we implement FromIterator? If so which insert should we use? + (At the moment we do implement it using insert_platonic()) -- use it in robot_Sweet_graph for a bit before publishing - -# final checks - -- remove most rustfmt::skips and cargo fmt -- check toml meta-data, github meta-data and readme opener -- copy map to set again -- review todo.txt -- copy readme to lib.rs docs again -- take a look around idiomatic rust for a bit first -- run is_labelled again and check they are accurate -- review method parameter names for all public functions -- update lines of code figures on docs -- add issues to github for all the caveats -- review caveats again -- run and fix cargo clippy - -- PUBLISH +#### PUBLISH # after publish tasks