superset_map

B-tree-backed map whose keys are distinct supersets.
git clone https://git.philomathiclife.com/repos/superset_map
Log | Files | Refs | README

commit 3677d89c53e4cbafbf18d003f596a39bf4eb928f
parent 354c2023385f3c32979c1b3e0a02ec363dc109ca
Author: Zack Newman <zack@philomathiclife.com>
Date:   Fri, 21 Nov 2025 20:51:19 -0700

address clippy lints for tests

Diffstat:
MCargo.toml | 20++++++++++++++++++--
MREADME.md | 9+++++++--
Msrc/superset_map.rs | 98+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Msrc/superset_set.rs | 26+++++++++++++++++++++-----
4 files changed, 104 insertions(+), 49 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" name = "superset_map" readme = "README.md" repository = "https://git.philomathiclife.com/repos/superset_map/" -version = "0.3.4" +version = "0.3.5" [lints.rust] ambiguous_negative_literals = { level = "deny", priority = -1 } @@ -81,6 +81,22 @@ pub_use = "allow" return_and_then = "allow" semicolon_outside_block = "allow" single_char_lifetime_names = "allow" +unseparated_literal_suffix = "allow" + +[package.metadata.docs.rs] +default-target = "x86_64-unknown-linux-gnu" +targets = [ + "aarch64-apple-darwin", + "aarch64-pc-windows-msvc", + "aarch64-unknown-linux-gnu", + "i686-pc-windows-msvc", + "i686-unknown-linux-gnu", + "x86_64-pc-windows-gnu", + "x86_64-pc-windows-msvc", + "x86_64-unknown-freebsd", + "x86_64-unknown-linux-musl", + "x86_64-unknown-netbsd" +] [dependencies] -zfc = { version = "0.4.4", default-features = false } +zfc = { version = "0.4.6", default-features = false } diff --git a/README.md b/README.md @@ -160,8 +160,13 @@ at your option. Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. -Before any PR is sent, `cargo clippy` and `cargo t` should be run for both. Additionally -`RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc --all-features` should be run to ensure documentation can be built. +Before any PR is sent, `cargo clippy --all-targets`, `cargo test --all-targets`, and `cargo test --doc` should be +run _for each possible combination of "features"_ using the nightly toolchain. One easy way to achieve this +is by invoking [`ci-cargo`](https://crates.io/crates/ci-cargo) as `ci-cargo clippy --all-targets test --all-targets` +in the `superset_map` directory. + +Last, `RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc` should be run to ensure documentation can be +built. ### Status diff --git a/src/superset_map.rs b/src/superset_map.rs @@ -753,14 +753,34 @@ mod tests { } impl Set for ClosedInterval { type Elem = usize; + #[expect(clippy::panic, reason = "want to crash when there is a bug")] + #[expect( + clippy::arithmetic_side_effects, + reason = "comment justifies correctness" + )] fn bounded_cardinality(&self) -> BoundedCardinality { BoundedCardinality::from_biguint_exact( - BigUint::from(self.max - self.min) + BigUint::from(1usize), + // We can add `BigUint`s. + BigUint::from(self.max.checked_sub(self.min).unwrap_or_else(|| { + panic!( + "superset_map::test::ClosedInterval must be created such that max is >= min" + ) + })) + BigUint::from(1usize), ) } + #[expect(clippy::panic, reason = "want to crash when there is a bug")] + #[expect( + clippy::arithmetic_side_effects, + reason = "comment justifies correctness" + )] fn cardinality(&self) -> Option<Cardinality> { Some(Cardinality::Finite( - BigUint::from(self.max - self.min) + BigUint::from(1usize), + // We can add `BigUint`s. + BigUint::from(self.max.checked_sub(self.min).unwrap_or_else(|| { + panic!( + "superset_map::test::ClosedInterval must be created such that max is >= min" + ) + })) + BigUint::from(1usize), )) } fn contains<Q>(&self, elem: &Q) -> bool @@ -782,7 +802,7 @@ mod tests { } impl SetOrd for ClosedInterval {} #[test] - fn test_insert() { + fn insert() { let mut map = SupersetMap::new(); _ = map.insert(ClosedInterval { min: 0, max: 3 }, ()); _ = map.insert(ClosedInterval { min: 0, max: 3 }, ()); @@ -794,22 +814,22 @@ mod tests { let mut keys = map.into_keys(); assert!( keys.next() - .map_or(false, |set| set == ClosedInterval { min: 0, max: 4 }) + .is_some_and(|set| set == ClosedInterval { min: 0, max: 4 }) ); assert!( keys.next() - .map_or(false, |set| set == ClosedInterval { min: 2, max: 7 }) + .is_some_and(|set| set == ClosedInterval { min: 2, max: 7 }) ); assert!( keys.next() - .map_or(false, |set| set == ClosedInterval { min: 10, max: 17 }) + .is_some_and(|set| set == ClosedInterval { min: 10, max: 17 }) ); assert!(keys.next().is_none()); assert!(keys.next().is_none()); assert!(keys.next().is_none()); } #[test] - fn test_append() { + fn append() { let mut map = SupersetMap::new(); _ = map.insert(ClosedInterval { min: 0, max: 3 }, ()); _ = map.insert(ClosedInterval { min: 0, max: 3 }, ()); @@ -826,26 +846,26 @@ mod tests { let mut keys = map.into_keys(); assert!( keys.next() - .map_or(false, |set| set == ClosedInterval { min: 0, max: 4 }) + .is_some_and(|set| set == ClosedInterval { min: 0, max: 4 }) ); assert!( keys.next() - .map_or(false, |set| set == ClosedInterval { min: 1, max: 14 }) + .is_some_and(|set| set == ClosedInterval { min: 1, max: 14 }) ); assert!( keys.next() - .map_or(false, |set| set == ClosedInterval { min: 10, max: 17 }) + .is_some_and(|set| set == ClosedInterval { min: 10, max: 17 }) ); assert!( keys.next() - .map_or(false, |set| set == ClosedInterval { min: 11, max: 18 }) + .is_some_and(|set| set == ClosedInterval { min: 11, max: 18 }) ); assert!(keys.next().is_none()); assert!(keys.next().is_none()); assert!(keys.next().is_none()); } #[test] - fn test_contains() { + fn contains() { let mut map = SupersetMap::new(); _ = map.insert(ClosedInterval { min: 0, max: 3 }, ()); _ = map.insert(ClosedInterval { min: 0, max: 3 }, ()); @@ -868,7 +888,7 @@ mod tests { assert!(!map.contains_superset(&ClosedInterval { min: 210, max: 217 })); } #[test] - fn test_get() { + fn get() { let mut map = SupersetMap::new(); _ = map.insert(ClosedInterval { min: 0, max: 3 }, ()); _ = map.insert(ClosedInterval { min: 0, max: 3 }, ()); @@ -879,57 +899,55 @@ mod tests { _ = map.insert(ClosedInterval { min: 10, max: 17 }, ()); assert!( map.get_greatest_proper_subset_key_value(&ClosedInterval { min: 0, max: 10 }) - .map_or(false, |(key, _)| *key == ClosedInterval { min: 2, max: 7 }) + .is_some_and(|info| *info.0 == ClosedInterval { min: 2, max: 7 }) ); assert!( map.get_greatest_proper_subset_key_value(&ClosedInterval { min: 10, max: 17 }) - .map_or(true, |_| false) + .is_none() ); assert!( map.get_greatest_proper_subset_key_value(&ClosedInterval { min: 210, max: 217 }) - .map_or(true, |_| false) + .is_none() ); assert!( map.get_least_proper_superset_key_value(&ClosedInterval { min: 3, max: 4 }) - .map_or(false, |(key, _)| *key == ClosedInterval { min: 0, max: 4 }) + .is_some_and(|info| *info.0 == ClosedInterval { min: 0, max: 4 }) ); assert!( map.get_least_proper_superset_key_value(&ClosedInterval { min: 10, max: 17 }) - .map_or(true, |_| false) + .is_none() ); assert!( map.get_least_proper_superset_key_value(&ClosedInterval { min: 210, max: 217 }) - .map_or(true, |_| false) + .is_none() ); assert!( map.get_greatest_subset_key_value(&ClosedInterval { min: 0, max: 10 }) - .map_or(false, |(key, _)| *key == ClosedInterval { min: 2, max: 7 }) + .is_some_and(|info| *info.0 == ClosedInterval { min: 2, max: 7 }) ); assert!( map.get_greatest_subset_key_value(&ClosedInterval { min: 10, max: 17 }) - .map_or(false, |(key, _)| *key - == ClosedInterval { min: 10, max: 17 }) + .is_some_and(|info| *info.0 == ClosedInterval { min: 10, max: 17 }) ); assert!( map.get_greatest_subset_key_value(&ClosedInterval { min: 210, max: 217 }) - .map_or(true, |_| false) + .is_none() ); assert!( map.get_least_superset_key_value(&ClosedInterval { min: 3, max: 4 }) - .map_or(false, |(key, _)| *key == ClosedInterval { min: 0, max: 4 }) + .is_some_and(|info| *info.0 == ClosedInterval { min: 0, max: 4 }) ); assert!( map.get_least_superset_key_value(&ClosedInterval { min: 10, max: 17 }) - .map_or(false, |(key, _)| *key - == ClosedInterval { min: 10, max: 17 }) + .is_some_and(|info| *info.0 == ClosedInterval { min: 10, max: 17 }) ); assert!( map.get_least_superset_key_value(&ClosedInterval { min: 210, max: 217 }) - .map_or(true, |_| false) + .is_none() ); } #[test] - fn test_remove() { + fn remove() { let mut map = SupersetMap::new(); _ = map.insert(ClosedInterval { min: 0, max: 3 }, ()); _ = map.insert(ClosedInterval { min: 0, max: 3 }, ()); @@ -940,51 +958,51 @@ mod tests { _ = map.insert(ClosedInterval { min: 10, max: 17 }, ()); assert!( map.remove_greatest_proper_subset(&ClosedInterval { min: 0, max: 10 }) - .map_or(false, |(key, _)| key == ClosedInterval { min: 2, max: 7 }) + .is_some_and(|info| info.0 == ClosedInterval { min: 2, max: 7 }) ); assert!( map.remove_greatest_proper_subset(&ClosedInterval { min: 10, max: 17 }) - .map_or(true, |_| false) + .is_none() ); assert!( map.remove_greatest_proper_subset(&ClosedInterval { min: 210, max: 217 }) - .map_or(true, |_| false) + .is_none() ); assert!( map.remove_least_proper_superset(&ClosedInterval { min: 3, max: 4 }) - .map_or(false, |(key, _)| key == ClosedInterval { min: 0, max: 4 }) + .is_some_and(|info| info.0 == ClosedInterval { min: 0, max: 4 }) ); assert!( map.remove_least_proper_superset(&ClosedInterval { min: 10, max: 17 }) - .map_or(true, |_| false) + .is_none() ); assert!( map.remove_least_proper_superset(&ClosedInterval { min: 210, max: 217 }) - .map_or(true, |_| false) + .is_none() ); assert!( map.remove_greatest_subset(&ClosedInterval { min: 0, max: 10 }) - .map_or(true, |_| false) + .is_none() ); assert!( map.remove_greatest_subset(&ClosedInterval { min: 10, max: 17 }) - .map_or(false, |(key, _)| key == ClosedInterval { min: 10, max: 17 }) + .is_some_and(|info| info.0 == ClosedInterval { min: 10, max: 17 }) ); assert!( map.remove_greatest_subset(&ClosedInterval { min: 210, max: 217 }) - .map_or(true, |_| false) + .is_none() ); assert!( map.remove_least_superset(&ClosedInterval { min: 3, max: 4 }) - .map_or(true, |_| false) + .is_none() ); assert!( map.remove_least_superset(&ClosedInterval { min: 10, max: 17 }) - .map_or(true, |_| false) + .is_none() ); assert!( map.remove_least_superset(&ClosedInterval { min: 210, max: 217 }) - .map_or(true, |_| false) + .is_none() ); let mut map2 = SupersetMap::new(); _ = map2.insert(ClosedInterval { min: 0, max: 3 }, ()); diff --git a/src/superset_set.rs b/src/superset_set.rs @@ -843,14 +843,30 @@ mod tests { } impl Set for ClosedInterval { type Elem = usize; + #[expect(clippy::panic, reason = "want to crash when there is a bug")] + #[expect( + clippy::arithmetic_side_effects, + reason = "comment justifies correctness" + )] fn bounded_cardinality(&self) -> BoundedCardinality { BoundedCardinality::from_biguint_exact( - BigUint::from(self.max - self.min) + BigUint::from(1usize), + // `BigUint`s can always be added together. + BigUint::from(self.max.checked_sub(self.min).unwrap_or_else(|| { + panic!("superset_set::test::ClosedInterval must have max >= min") + })) + BigUint::from(1usize), ) } + #[expect(clippy::panic, reason = "want to crash when there is a bug")] + #[expect( + clippy::arithmetic_side_effects, + reason = "comment justifies correctness" + )] fn cardinality(&self) -> Option<Cardinality> { Some(Cardinality::Finite( - BigUint::from(self.max - self.min) + BigUint::from(1usize), + // `BigUint`s can always be added together. + BigUint::from(self.max.checked_sub(self.min).unwrap_or_else(|| { + panic!("superset_set::test::ClosedInterval must have max >= min") + })) + BigUint::from(1usize), )) } fn contains<Q>(&self, elem: &Q) -> bool @@ -872,7 +888,7 @@ mod tests { } impl SetOrd for ClosedInterval {} #[test] - fn test_union() { + fn union() { let mut set1 = SupersetSet::new(); _ = set1.insert(ClosedInterval { min: 14, max: 19 }); _ = set1.insert(ClosedInterval { min: 10, max: 12 }); @@ -902,7 +918,7 @@ mod tests { assert!(union.next().is_none()); } #[test] - fn test_intersection() { + fn intersection() { let mut set1 = SupersetSet::new(); _ = set1.insert(ClosedInterval { min: 14, max: 19 }); _ = set1.insert(ClosedInterval { min: 10, max: 12 }); @@ -931,7 +947,7 @@ mod tests { assert!(intersection.next().is_none()); } #[test] - fn test_replace() { + fn replace() { let mut set = SupersetSet::new(); _ = set.insert(ClosedInterval { min: 14, max: 19 }); _ = set.insert(ClosedInterval { min: 10, max: 12 });