commit c4a185bad9b56ef0366f09354784f25ad09aeb5a
parent 99526edfaeed8e16d7c8e977db692de5b5fadd8f
Author: Zack Newman <zack@philomathiclife.com>
Date: Mon, 13 Jul 2026 13:31:49 -0600
update deps and lints. move unit tests
Diffstat:
5 files changed, 502 insertions(+), 489 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.6"
+version = "0.3.7"
[lints.rust]
deprecated-safe = { level = "deny", priority = -1 }
@@ -27,12 +27,14 @@ unused = { level = "deny", priority = -1 }
warnings = { level = "deny", priority = -1 }
ambiguous-negative-literals = { level = "deny", priority = -1 }
closure-returning-async-block = { level = "deny", priority = -1 }
+dead-code-pub-in-binary = { level = "deny", priority = -1 }
deprecated-in-future = { level = "deny", priority = -1 }
+#deprecated-llvm-intrinsic = { level = "deny", priority = -1 }
deref-into-dyn-supertrait = { level = "deny", priority = -1 }
ffi-unwind-calls = { level = "deny", priority = -1 }
#fuzzy-provenance-casts = { level = "deny", priority = -1 }
impl-trait-redundant-captures = { level = "deny", priority = -1 }
-linker-messages = { level = "deny", priority = -1 }
+linker-info = { level = "deny", priority = -1 }
#lossy-provenance-casts = { level = "deny", priority = -1 }
macro-use-extern-crate = { level = "deny", priority = -1 }
meta-variable-misuse = { level = "deny", priority = -1 }
@@ -77,10 +79,12 @@ suspicious = { level = "deny", priority = -1 }
arbitrary_source_item_ordering = "allow"
blanket_clippy_restriction_lints = "allow"
implicit_return = "allow"
+inline_trait_bounds = "allow"
min_ident_chars = "allow"
missing_trait_methods = "allow"
pub_use = "allow"
return_and_then = "allow"
+self_named_module_files = "allow"
semicolon_outside_block = "allow"
single_char_lifetime_names = "allow"
unseparated_literal_suffix = "allow"
@@ -104,4 +108,4 @@ targets = [
]
[dependencies]
-zfc = { version = "0.4.7", default-features = false }
+zfc = { version = "0.5.0", default-features = false }
diff --git a/src/superset_map.rs b/src/superset_map.rs
@@ -1,4 +1,7 @@
extern crate alloc;
+/// Unit tests.
+#[cfg(test)]
+mod tests;
use crate::SetOrd;
use alloc::collections::btree_map::{
BTreeMap, CursorMut, IntoIter, IntoKeys, IntoValues, Iter, IterMut, Keys, OccupiedEntry, Range,
@@ -713,315 +716,3 @@ impl<'a, K, V> IntoIterator for &'a mut SupersetMap<K, V> {
self.iter_mut()
}
}
-#[cfg(test)]
-mod tests {
- use super::{
- super::zfc::{BoundedCardinality, Cardinality, Set, num_bigint::BigUint},
- SetOrd, SupersetMap,
- };
- use core::{borrow::Borrow, cmp::Ordering};
- #[derive(Eq, PartialEq)]
- struct ClosedInterval {
- min: usize,
- max: usize,
- }
- impl PartialOrd<Self> for ClosedInterval {
- fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
- Some(self.cmp(other))
- }
- }
- impl Ord for ClosedInterval {
- fn cmp(&self, other: &Self) -> Ordering {
- match self.min.cmp(&other.min) {
- Ordering::Less => {
- if self.max >= other.max {
- Ordering::Greater
- } else {
- Ordering::Less
- }
- }
- Ordering::Equal => self.max.cmp(&other.max),
- Ordering::Greater => {
- if self.max > other.max {
- Ordering::Greater
- } else {
- Ordering::Less
- }
- }
- }
- }
- }
- 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(
- // 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(
- // 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
- where
- Q: ?Sized + Borrow<Self::Elem> + Eq,
- {
- self.min <= *elem.borrow() && self.max >= *elem.borrow()
- }
- fn is_proper_subset(&self, val: &Self) -> bool {
- match self.min.cmp(&val.min) {
- Ordering::Less => false,
- Ordering::Equal => self.max < val.max,
- Ordering::Greater => self.max <= val.max,
- }
- }
- fn is_subset(&self, val: &Self) -> bool {
- self.min >= val.min && self.max <= val.max
- }
- }
- impl SetOrd for ClosedInterval {}
- #[test]
- fn insert() {
- let mut map = SupersetMap::new();
- _ = map.insert(ClosedInterval { min: 0, max: 3 }, ());
- _ = map.insert(ClosedInterval { min: 0, max: 3 }, ());
- _ = map.insert(ClosedInterval { min: 0, max: 4 }, ());
- _ = map.insert(ClosedInterval { min: 1, max: 4 }, ());
- _ = map.insert(ClosedInterval { min: 4, max: 6 }, ());
- _ = map.insert(ClosedInterval { min: 2, max: 7 }, ());
- _ = map.insert(ClosedInterval { min: 10, max: 17 }, ());
- let mut keys = map.into_keys();
- assert!(
- keys.next()
- .is_some_and(|set| set == ClosedInterval { min: 0, max: 4 })
- );
- assert!(
- keys.next()
- .is_some_and(|set| set == ClosedInterval { min: 2, max: 7 })
- );
- assert!(
- keys.next()
- .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 append() {
- let mut map = SupersetMap::new();
- _ = map.insert(ClosedInterval { min: 0, max: 3 }, ());
- _ = map.insert(ClosedInterval { min: 0, max: 3 }, ());
- _ = map.insert(ClosedInterval { min: 0, max: 4 }, ());
- _ = map.insert(ClosedInterval { min: 1, max: 4 }, ());
- _ = map.insert(ClosedInterval { min: 4, max: 6 }, ());
- _ = map.insert(ClosedInterval { min: 2, max: 7 }, ());
- _ = map.insert(ClosedInterval { min: 10, max: 17 }, ());
- let mut map2 = SupersetMap::new();
- _ = map2.insert(ClosedInterval { min: 0, max: 1 }, ());
- _ = map2.insert(ClosedInterval { min: 1, max: 14 }, ());
- _ = map2.insert(ClosedInterval { min: 11, max: 18 }, ());
- map.append(map2);
- let mut keys = map.into_keys();
- assert!(
- keys.next()
- .is_some_and(|set| set == ClosedInterval { min: 0, max: 4 })
- );
- assert!(
- keys.next()
- .is_some_and(|set| set == ClosedInterval { min: 1, max: 14 })
- );
- assert!(
- keys.next()
- .is_some_and(|set| set == ClosedInterval { min: 10, max: 17 })
- );
- assert!(
- keys.next()
- .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 contains() {
- let mut map = SupersetMap::new();
- _ = map.insert(ClosedInterval { min: 0, max: 3 }, ());
- _ = map.insert(ClosedInterval { min: 0, max: 3 }, ());
- _ = map.insert(ClosedInterval { min: 0, max: 4 }, ());
- _ = map.insert(ClosedInterval { min: 1, max: 4 }, ());
- _ = map.insert(ClosedInterval { min: 4, max: 6 }, ());
- _ = map.insert(ClosedInterval { min: 2, max: 7 }, ());
- _ = map.insert(ClosedInterval { min: 10, max: 17 }, ());
- assert!(map.contains_proper_subset(&ClosedInterval { min: 0, max: 10 }));
- assert!(!map.contains_proper_subset(&ClosedInterval { min: 10, max: 17 }));
- assert!(!map.contains_proper_subset(&ClosedInterval { min: 210, max: 217 }));
- assert!(map.contains_proper_superset(&ClosedInterval { min: 0, max: 1 }));
- assert!(!map.contains_proper_superset(&ClosedInterval { min: 10, max: 17 }));
- assert!(!map.contains_proper_superset(&ClosedInterval { min: 210, max: 217 }));
- assert!(map.contains_subset(&ClosedInterval { min: 0, max: 10 }));
- assert!(map.contains_subset(&ClosedInterval { min: 10, max: 17 }));
- assert!(!map.contains_subset(&ClosedInterval { min: 210, max: 217 }));
- assert!(map.contains_superset(&ClosedInterval { min: 0, max: 1 }));
- assert!(map.contains_superset(&ClosedInterval { min: 10, max: 17 }));
- assert!(!map.contains_superset(&ClosedInterval { min: 210, max: 217 }));
- }
- #[test]
- fn get() {
- let mut map = SupersetMap::new();
- _ = map.insert(ClosedInterval { min: 0, max: 3 }, ());
- _ = map.insert(ClosedInterval { min: 0, max: 3 }, ());
- _ = map.insert(ClosedInterval { min: 0, max: 4 }, ());
- _ = map.insert(ClosedInterval { min: 1, max: 4 }, ());
- _ = map.insert(ClosedInterval { min: 4, max: 6 }, ());
- _ = map.insert(ClosedInterval { min: 2, max: 7 }, ());
- _ = map.insert(ClosedInterval { min: 10, max: 17 }, ());
- assert!(
- map.get_greatest_proper_subset_key_value(&ClosedInterval { min: 0, max: 10 })
- .is_some_and(|info| *info.0 == ClosedInterval { min: 2, max: 7 })
- );
- assert!(
- map.get_greatest_proper_subset_key_value(&ClosedInterval { min: 10, max: 17 })
- .is_none()
- );
- assert!(
- map.get_greatest_proper_subset_key_value(&ClosedInterval { min: 210, max: 217 })
- .is_none()
- );
- assert!(
- map.get_least_proper_superset_key_value(&ClosedInterval { min: 3, 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 })
- .is_none()
- );
- assert!(
- map.get_least_proper_superset_key_value(&ClosedInterval { min: 210, max: 217 })
- .is_none()
- );
- assert!(
- map.get_greatest_subset_key_value(&ClosedInterval { min: 0, max: 10 })
- .is_some_and(|info| *info.0 == ClosedInterval { min: 2, max: 7 })
- );
- assert!(
- map.get_greatest_subset_key_value(&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 })
- .is_none()
- );
- assert!(
- map.get_least_superset_key_value(&ClosedInterval { min: 3, 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 })
- .is_some_and(|info| *info.0 == ClosedInterval { min: 10, max: 17 })
- );
- assert!(
- map.get_least_superset_key_value(&ClosedInterval { min: 210, max: 217 })
- .is_none()
- );
- }
- #[test]
- fn remove() {
- let mut map = SupersetMap::new();
- _ = map.insert(ClosedInterval { min: 0, max: 3 }, ());
- _ = map.insert(ClosedInterval { min: 0, max: 3 }, ());
- _ = map.insert(ClosedInterval { min: 0, max: 4 }, ());
- _ = map.insert(ClosedInterval { min: 1, max: 4 }, ());
- _ = map.insert(ClosedInterval { min: 4, max: 6 }, ());
- _ = map.insert(ClosedInterval { min: 2, max: 7 }, ());
- _ = map.insert(ClosedInterval { min: 10, max: 17 }, ());
- assert!(
- map.remove_greatest_proper_subset(&ClosedInterval { min: 0, max: 10 })
- .is_some_and(|info| info.0 == ClosedInterval { min: 2, max: 7 })
- );
- assert!(
- map.remove_greatest_proper_subset(&ClosedInterval { min: 10, max: 17 })
- .is_none()
- );
- assert!(
- map.remove_greatest_proper_subset(&ClosedInterval { min: 210, max: 217 })
- .is_none()
- );
- assert!(
- map.remove_least_proper_superset(&ClosedInterval { min: 3, max: 4 })
- .is_some_and(|info| info.0 == ClosedInterval { min: 0, max: 4 })
- );
- assert!(
- map.remove_least_proper_superset(&ClosedInterval { min: 10, max: 17 })
- .is_none()
- );
- assert!(
- map.remove_least_proper_superset(&ClosedInterval { min: 210, max: 217 })
- .is_none()
- );
- assert!(
- map.remove_greatest_subset(&ClosedInterval { min: 0, max: 10 })
- .is_none()
- );
- assert!(
- map.remove_greatest_subset(&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 })
- .is_none()
- );
- assert!(
- map.remove_least_superset(&ClosedInterval { min: 3, max: 4 })
- .is_none()
- );
- assert!(
- map.remove_least_superset(&ClosedInterval { min: 10, max: 17 })
- .is_none()
- );
- assert!(
- map.remove_least_superset(&ClosedInterval { min: 210, max: 217 })
- .is_none()
- );
- let mut map2 = SupersetMap::new();
- _ = map2.insert(ClosedInterval { min: 0, max: 3 }, ());
- _ = map2.insert(ClosedInterval { min: 0, max: 3 }, ());
- _ = map2.insert(ClosedInterval { min: 0, max: 4 }, ());
- _ = map2.insert(ClosedInterval { min: 1, max: 4 }, ());
- _ = map2.insert(ClosedInterval { min: 4, max: 6 }, ());
- _ = map2.insert(ClosedInterval { min: 2, max: 7 }, ());
- _ = map2.insert(ClosedInterval { min: 10, max: 17 }, ());
- assert!(map2.remove_supersets(&ClosedInterval { min: 0, max: 20 }) == 0);
- assert!(map2.remove_subsets(&ClosedInterval { min: 0, max: 1 }) == 0);
- assert!(map2.remove_subsets(&ClosedInterval { min: 0, max: 20 }) == 3);
- _ = map2.insert(ClosedInterval { min: 0, max: 3 }, ());
- _ = map2.insert(ClosedInterval { min: 0, max: 3 }, ());
- _ = map2.insert(ClosedInterval { min: 0, max: 4 }, ());
- _ = map2.insert(ClosedInterval { min: 1, max: 4 }, ());
- _ = map2.insert(ClosedInterval { min: 4, max: 6 }, ());
- _ = map2.insert(ClosedInterval { min: 2, max: 7 }, ());
- _ = map2.insert(ClosedInterval { min: 10, max: 17 }, ());
- assert!(map2.remove_supersets(&ClosedInterval { min: 3, max: 4 }) == 2);
- }
-}
diff --git a/src/superset_map/tests.rs b/src/superset_map/tests.rs
@@ -0,0 +1,308 @@
+use super::{
+ super::zfc::{BoundedCardinality, Cardinality, Set, num_bigint::BigUint},
+ SetOrd, SupersetMap,
+};
+use core::{borrow::Borrow, cmp::Ordering};
+#[derive(Eq, PartialEq)]
+struct ClosedInterval {
+ min: usize,
+ max: usize,
+}
+impl PartialOrd<Self> for ClosedInterval {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ Some(self.cmp(other))
+ }
+}
+impl Ord for ClosedInterval {
+ fn cmp(&self, other: &Self) -> Ordering {
+ match self.min.cmp(&other.min) {
+ Ordering::Less => {
+ if self.max >= other.max {
+ Ordering::Greater
+ } else {
+ Ordering::Less
+ }
+ }
+ Ordering::Equal => self.max.cmp(&other.max),
+ Ordering::Greater => {
+ if self.max > other.max {
+ Ordering::Greater
+ } else {
+ Ordering::Less
+ }
+ }
+ }
+ }
+}
+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(
+ // 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(
+ // 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
+ where
+ Q: ?Sized + Borrow<Self::Elem> + Eq,
+ {
+ self.min <= *elem.borrow() && self.max >= *elem.borrow()
+ }
+ fn is_proper_subset(&self, val: &Self) -> bool {
+ match self.min.cmp(&val.min) {
+ Ordering::Less => false,
+ Ordering::Equal => self.max < val.max,
+ Ordering::Greater => self.max <= val.max,
+ }
+ }
+ fn is_subset(&self, val: &Self) -> bool {
+ self.min >= val.min && self.max <= val.max
+ }
+}
+impl SetOrd for ClosedInterval {}
+#[test]
+fn insert() {
+ let mut map = SupersetMap::new();
+ _ = map.insert(ClosedInterval { min: 0, max: 3 }, ());
+ _ = map.insert(ClosedInterval { min: 0, max: 3 }, ());
+ _ = map.insert(ClosedInterval { min: 0, max: 4 }, ());
+ _ = map.insert(ClosedInterval { min: 1, max: 4 }, ());
+ _ = map.insert(ClosedInterval { min: 4, max: 6 }, ());
+ _ = map.insert(ClosedInterval { min: 2, max: 7 }, ());
+ _ = map.insert(ClosedInterval { min: 10, max: 17 }, ());
+ let mut keys = map.into_keys();
+ assert!(
+ keys.next()
+ .is_some_and(|set| set == ClosedInterval { min: 0, max: 4 })
+ );
+ assert!(
+ keys.next()
+ .is_some_and(|set| set == ClosedInterval { min: 2, max: 7 })
+ );
+ assert!(
+ keys.next()
+ .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 append() {
+ let mut map = SupersetMap::new();
+ _ = map.insert(ClosedInterval { min: 0, max: 3 }, ());
+ _ = map.insert(ClosedInterval { min: 0, max: 3 }, ());
+ _ = map.insert(ClosedInterval { min: 0, max: 4 }, ());
+ _ = map.insert(ClosedInterval { min: 1, max: 4 }, ());
+ _ = map.insert(ClosedInterval { min: 4, max: 6 }, ());
+ _ = map.insert(ClosedInterval { min: 2, max: 7 }, ());
+ _ = map.insert(ClosedInterval { min: 10, max: 17 }, ());
+ let mut map2 = SupersetMap::new();
+ _ = map2.insert(ClosedInterval { min: 0, max: 1 }, ());
+ _ = map2.insert(ClosedInterval { min: 1, max: 14 }, ());
+ _ = map2.insert(ClosedInterval { min: 11, max: 18 }, ());
+ map.append(map2);
+ let mut keys = map.into_keys();
+ assert!(
+ keys.next()
+ .is_some_and(|set| set == ClosedInterval { min: 0, max: 4 })
+ );
+ assert!(
+ keys.next()
+ .is_some_and(|set| set == ClosedInterval { min: 1, max: 14 })
+ );
+ assert!(
+ keys.next()
+ .is_some_and(|set| set == ClosedInterval { min: 10, max: 17 })
+ );
+ assert!(
+ keys.next()
+ .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 contains() {
+ let mut map = SupersetMap::new();
+ _ = map.insert(ClosedInterval { min: 0, max: 3 }, ());
+ _ = map.insert(ClosedInterval { min: 0, max: 3 }, ());
+ _ = map.insert(ClosedInterval { min: 0, max: 4 }, ());
+ _ = map.insert(ClosedInterval { min: 1, max: 4 }, ());
+ _ = map.insert(ClosedInterval { min: 4, max: 6 }, ());
+ _ = map.insert(ClosedInterval { min: 2, max: 7 }, ());
+ _ = map.insert(ClosedInterval { min: 10, max: 17 }, ());
+ assert!(map.contains_proper_subset(&ClosedInterval { min: 0, max: 10 }));
+ assert!(!map.contains_proper_subset(&ClosedInterval { min: 10, max: 17 }));
+ assert!(!map.contains_proper_subset(&ClosedInterval { min: 210, max: 217 }));
+ assert!(map.contains_proper_superset(&ClosedInterval { min: 0, max: 1 }));
+ assert!(!map.contains_proper_superset(&ClosedInterval { min: 10, max: 17 }));
+ assert!(!map.contains_proper_superset(&ClosedInterval { min: 210, max: 217 }));
+ assert!(map.contains_subset(&ClosedInterval { min: 0, max: 10 }));
+ assert!(map.contains_subset(&ClosedInterval { min: 10, max: 17 }));
+ assert!(!map.contains_subset(&ClosedInterval { min: 210, max: 217 }));
+ assert!(map.contains_superset(&ClosedInterval { min: 0, max: 1 }));
+ assert!(map.contains_superset(&ClosedInterval { min: 10, max: 17 }));
+ assert!(!map.contains_superset(&ClosedInterval { min: 210, max: 217 }));
+}
+#[test]
+fn get() {
+ let mut map = SupersetMap::new();
+ _ = map.insert(ClosedInterval { min: 0, max: 3 }, ());
+ _ = map.insert(ClosedInterval { min: 0, max: 3 }, ());
+ _ = map.insert(ClosedInterval { min: 0, max: 4 }, ());
+ _ = map.insert(ClosedInterval { min: 1, max: 4 }, ());
+ _ = map.insert(ClosedInterval { min: 4, max: 6 }, ());
+ _ = map.insert(ClosedInterval { min: 2, max: 7 }, ());
+ _ = map.insert(ClosedInterval { min: 10, max: 17 }, ());
+ assert!(
+ map.get_greatest_proper_subset_key_value(&ClosedInterval { min: 0, max: 10 })
+ .is_some_and(|info| *info.0 == ClosedInterval { min: 2, max: 7 })
+ );
+ assert!(
+ map.get_greatest_proper_subset_key_value(&ClosedInterval { min: 10, max: 17 })
+ .is_none()
+ );
+ assert!(
+ map.get_greatest_proper_subset_key_value(&ClosedInterval { min: 210, max: 217 })
+ .is_none()
+ );
+ assert!(
+ map.get_least_proper_superset_key_value(&ClosedInterval { min: 3, 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 })
+ .is_none()
+ );
+ assert!(
+ map.get_least_proper_superset_key_value(&ClosedInterval { min: 210, max: 217 })
+ .is_none()
+ );
+ assert!(
+ map.get_greatest_subset_key_value(&ClosedInterval { min: 0, max: 10 })
+ .is_some_and(|info| *info.0 == ClosedInterval { min: 2, max: 7 })
+ );
+ assert!(
+ map.get_greatest_subset_key_value(&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 })
+ .is_none()
+ );
+ assert!(
+ map.get_least_superset_key_value(&ClosedInterval { min: 3, 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 })
+ .is_some_and(|info| *info.0 == ClosedInterval { min: 10, max: 17 })
+ );
+ assert!(
+ map.get_least_superset_key_value(&ClosedInterval { min: 210, max: 217 })
+ .is_none()
+ );
+}
+#[test]
+fn remove() {
+ let mut map = SupersetMap::new();
+ _ = map.insert(ClosedInterval { min: 0, max: 3 }, ());
+ _ = map.insert(ClosedInterval { min: 0, max: 3 }, ());
+ _ = map.insert(ClosedInterval { min: 0, max: 4 }, ());
+ _ = map.insert(ClosedInterval { min: 1, max: 4 }, ());
+ _ = map.insert(ClosedInterval { min: 4, max: 6 }, ());
+ _ = map.insert(ClosedInterval { min: 2, max: 7 }, ());
+ _ = map.insert(ClosedInterval { min: 10, max: 17 }, ());
+ assert!(
+ map.remove_greatest_proper_subset(&ClosedInterval { min: 0, max: 10 })
+ .is_some_and(|info| info.0 == ClosedInterval { min: 2, max: 7 })
+ );
+ assert!(
+ map.remove_greatest_proper_subset(&ClosedInterval { min: 10, max: 17 })
+ .is_none()
+ );
+ assert!(
+ map.remove_greatest_proper_subset(&ClosedInterval { min: 210, max: 217 })
+ .is_none()
+ );
+ assert!(
+ map.remove_least_proper_superset(&ClosedInterval { min: 3, max: 4 })
+ .is_some_and(|info| info.0 == ClosedInterval { min: 0, max: 4 })
+ );
+ assert!(
+ map.remove_least_proper_superset(&ClosedInterval { min: 10, max: 17 })
+ .is_none()
+ );
+ assert!(
+ map.remove_least_proper_superset(&ClosedInterval { min: 210, max: 217 })
+ .is_none()
+ );
+ assert!(
+ map.remove_greatest_subset(&ClosedInterval { min: 0, max: 10 })
+ .is_none()
+ );
+ assert!(
+ map.remove_greatest_subset(&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 })
+ .is_none()
+ );
+ assert!(
+ map.remove_least_superset(&ClosedInterval { min: 3, max: 4 })
+ .is_none()
+ );
+ assert!(
+ map.remove_least_superset(&ClosedInterval { min: 10, max: 17 })
+ .is_none()
+ );
+ assert!(
+ map.remove_least_superset(&ClosedInterval { min: 210, max: 217 })
+ .is_none()
+ );
+ let mut map2 = SupersetMap::new();
+ _ = map2.insert(ClosedInterval { min: 0, max: 3 }, ());
+ _ = map2.insert(ClosedInterval { min: 0, max: 3 }, ());
+ _ = map2.insert(ClosedInterval { min: 0, max: 4 }, ());
+ _ = map2.insert(ClosedInterval { min: 1, max: 4 }, ());
+ _ = map2.insert(ClosedInterval { min: 4, max: 6 }, ());
+ _ = map2.insert(ClosedInterval { min: 2, max: 7 }, ());
+ _ = map2.insert(ClosedInterval { min: 10, max: 17 }, ());
+ assert_eq!(
+ map2.remove_supersets(&ClosedInterval { min: 0, max: 20 }),
+ 0
+ );
+ assert_eq!(map2.remove_subsets(&ClosedInterval { min: 0, max: 1 }), 0);
+ assert_eq!(map2.remove_subsets(&ClosedInterval { min: 0, max: 20 }), 3);
+ _ = map2.insert(ClosedInterval { min: 0, max: 3 }, ());
+ _ = map2.insert(ClosedInterval { min: 0, max: 3 }, ());
+ _ = map2.insert(ClosedInterval { min: 0, max: 4 }, ());
+ _ = map2.insert(ClosedInterval { min: 1, max: 4 }, ());
+ _ = map2.insert(ClosedInterval { min: 4, max: 6 }, ());
+ _ = map2.insert(ClosedInterval { min: 2, max: 7 }, ());
+ _ = map2.insert(ClosedInterval { min: 10, max: 17 }, ());
+ assert_eq!(map2.remove_supersets(&ClosedInterval { min: 3, max: 4 }), 2);
+}
diff --git a/src/superset_set.rs b/src/superset_set.rs
@@ -1,4 +1,7 @@
extern crate alloc;
+/// Unit tests.
+#[cfg(test)]
+mod tests;
use crate::{
SetOrd, SupersetMap,
zfc::{BoundedCardinality, Cardinality, Set},
@@ -803,177 +806,3 @@ where
}
}
}
-#[cfg(test)]
-mod tests {
- use super::{
- super::zfc::{BoundedCardinality, Cardinality, Set, num_bigint::BigUint},
- SetOrd, SupersetSet,
- };
- use core::{borrow::Borrow, cmp::Ordering};
- #[derive(Eq, PartialEq)]
- struct ClosedInterval {
- min: usize,
- max: usize,
- }
- impl PartialOrd<Self> for ClosedInterval {
- fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
- Some(self.cmp(other))
- }
- }
- impl Ord for ClosedInterval {
- fn cmp(&self, other: &Self) -> Ordering {
- match self.min.cmp(&other.min) {
- Ordering::Less => {
- if self.max >= other.max {
- Ordering::Greater
- } else {
- Ordering::Less
- }
- }
- Ordering::Equal => self.max.cmp(&other.max),
- Ordering::Greater => {
- if self.max > other.max {
- Ordering::Greater
- } else {
- Ordering::Less
- }
- }
- }
- }
- }
- 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`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`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
- where
- Q: ?Sized + Borrow<Self::Elem> + Eq,
- {
- self.min <= *elem.borrow() && self.max >= *elem.borrow()
- }
- fn is_proper_subset(&self, val: &Self) -> bool {
- match self.min.cmp(&val.min) {
- Ordering::Less => false,
- Ordering::Equal => self.max < val.max,
- Ordering::Greater => self.max <= val.max,
- }
- }
- fn is_subset(&self, val: &Self) -> bool {
- self.min >= val.min && self.max <= val.max
- }
- }
- impl SetOrd for ClosedInterval {}
- #[test]
- fn union() {
- let mut set1 = SupersetSet::new();
- _ = set1.insert(ClosedInterval { min: 14, max: 19 });
- _ = set1.insert(ClosedInterval { min: 10, max: 12 });
- _ = set1.insert(ClosedInterval { min: 0, max: 3 });
- _ = set1.insert(ClosedInterval { min: 0, max: 2 });
- _ = set1.insert(ClosedInterval { min: 1, max: 4 });
- _ = set1.insert(ClosedInterval { min: 20, max: 22 });
- _ = set1.insert(ClosedInterval { min: 25, max: 26 });
- _ = set1.insert(ClosedInterval { min: 26, max: 27 });
- let mut set2 = SupersetSet::new();
- _ = set2.insert(ClosedInterval { min: 10, max: 12 });
- _ = set2.insert(ClosedInterval { min: 14, max: 16 });
- _ = set2.insert(ClosedInterval { min: 0, max: 3 });
- _ = set2.insert(ClosedInterval { min: 3, max: 4 });
- _ = set2.insert(ClosedInterval { min: 23, max: 25 });
- _ = set2.insert(ClosedInterval { min: 25, max: 27 });
- let mut union = set1.union(&set2);
- assert!(union.next() == Some(&ClosedInterval { min: 0, max: 3 }));
- assert!(union.next() == Some(&ClosedInterval { min: 1, max: 4 }));
- assert!(union.next() == Some(&ClosedInterval { min: 10, max: 12 }));
- assert!(union.next() == Some(&ClosedInterval { min: 14, max: 19 }));
- assert!(union.next() == Some(&ClosedInterval { min: 20, max: 22 }));
- assert!(union.next() == Some(&ClosedInterval { min: 23, max: 25 }));
- assert!(union.next() == Some(&ClosedInterval { min: 25, max: 27 }));
- assert!(union.next().is_none());
- assert!(union.next().is_none());
- assert!(union.next().is_none());
- }
- #[test]
- fn intersection() {
- let mut set1 = SupersetSet::new();
- _ = set1.insert(ClosedInterval { min: 14, max: 19 });
- _ = set1.insert(ClosedInterval { min: 10, max: 12 });
- _ = set1.insert(ClosedInterval { min: 0, max: 3 });
- _ = set1.insert(ClosedInterval { min: 0, max: 2 });
- _ = set1.insert(ClosedInterval { min: 1, max: 4 });
- _ = set1.insert(ClosedInterval { min: 20, max: 22 });
- _ = set1.insert(ClosedInterval { min: 25, max: 26 });
- _ = set1.insert(ClosedInterval { min: 26, max: 27 });
- let mut set2 = SupersetSet::new();
- _ = set2.insert(ClosedInterval { min: 10, max: 12 });
- _ = set2.insert(ClosedInterval { min: 14, max: 16 });
- _ = set2.insert(ClosedInterval { min: 0, max: 3 });
- _ = set2.insert(ClosedInterval { min: 3, max: 4 });
- _ = set2.insert(ClosedInterval { min: 23, max: 25 });
- _ = set2.insert(ClosedInterval { min: 25, max: 27 });
- let mut intersection = set1.intersection(&set2);
- assert!(intersection.next() == Some(&ClosedInterval { min: 0, max: 3 }));
- assert!(intersection.next() == Some(&ClosedInterval { min: 3, max: 4 }));
- assert!(intersection.next() == Some(&ClosedInterval { min: 10, max: 12 }));
- assert!(intersection.next() == Some(&ClosedInterval { min: 14, max: 16 }));
- assert!(intersection.next() == Some(&ClosedInterval { min: 25, max: 26 }));
- assert!(intersection.next() == Some(&ClosedInterval { min: 26, max: 27 }));
- assert!(intersection.next().is_none());
- assert!(intersection.next().is_none());
- assert!(intersection.next().is_none());
- }
- #[test]
- fn replace() {
- let mut set = SupersetSet::new();
- _ = set.insert(ClosedInterval { min: 14, max: 19 });
- _ = set.insert(ClosedInterval { min: 10, max: 12 });
- _ = set.insert(ClosedInterval { min: 0, max: 3 });
- _ = set.insert(ClosedInterval { min: 0, max: 2 });
- _ = set.insert(ClosedInterval { min: 1, max: 4 });
- _ = set.insert(ClosedInterval { min: 20, max: 22 });
- _ = set.insert(ClosedInterval { min: 25, max: 26 });
- _ = set.insert(ClosedInterval { min: 26, max: 27 });
- // Does not replace proper supersets.
- assert!(
- set.replace(ClosedInterval { min: 20, max: 21 }).is_none()
- && set.contains(&ClosedInterval { min: 20, max: 22 })
- && set.contains_proper_superset(&ClosedInterval { min: 20, max: 21 })
- && !set.contains(&ClosedInterval { min: 20, max: 21 })
- );
- // Successful replace.
- assert!(
- set.replace(ClosedInterval { min: 0, max: 3 })
- == Some(ClosedInterval { min: 0, max: 3 })
- && set.contains(&ClosedInterval { min: 0, max: 3 })
- );
- // Replace is just an insert when a superset does not exist.
- assert!(
- set.replace(ClosedInterval { min: 100, max: 300 }).is_none()
- && set.contains(&ClosedInterval { min: 100, max: 300 })
- );
- }
-}
diff --git a/src/superset_set/tests.rs b/src/superset_set/tests.rs
@@ -0,0 +1,181 @@
+extern crate alloc;
+use super::Range;
+use super::{
+ super::zfc::{BoundedCardinality, Cardinality, Set, num_bigint::BigUint},
+ SetOrd, SupersetSet,
+};
+use alloc::collections::btree_map::BTreeMap;
+use core::{borrow::Borrow, cmp::Ordering};
+#[derive(Eq, PartialEq)]
+struct ClosedInterval {
+ min: usize,
+ max: usize,
+}
+impl PartialOrd<Self> for ClosedInterval {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ Some(self.cmp(other))
+ }
+}
+impl Ord for ClosedInterval {
+ fn cmp(&self, other: &Self) -> Ordering {
+ match self.min.cmp(&other.min) {
+ Ordering::Less => {
+ if self.max >= other.max {
+ Ordering::Greater
+ } else {
+ Ordering::Less
+ }
+ }
+ Ordering::Equal => self.max.cmp(&other.max),
+ Ordering::Greater => {
+ if self.max > other.max {
+ Ordering::Greater
+ } else {
+ Ordering::Less
+ }
+ }
+ }
+ }
+}
+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`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`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
+ where
+ Q: ?Sized + Borrow<Self::Elem> + Eq,
+ {
+ self.min <= *elem.borrow() && self.max >= *elem.borrow()
+ }
+ fn is_proper_subset(&self, val: &Self) -> bool {
+ match self.min.cmp(&val.min) {
+ Ordering::Less => false,
+ Ordering::Equal => self.max < val.max,
+ Ordering::Greater => self.max <= val.max,
+ }
+ }
+ fn is_subset(&self, val: &Self) -> bool {
+ self.min >= val.min && self.max <= val.max
+ }
+}
+impl SetOrd for ClosedInterval {}
+#[test]
+fn union() {
+ let mut set1 = SupersetSet::new();
+ _ = set1.insert(ClosedInterval { min: 14, max: 19 });
+ _ = set1.insert(ClosedInterval { min: 10, max: 12 });
+ _ = set1.insert(ClosedInterval { min: 0, max: 3 });
+ _ = set1.insert(ClosedInterval { min: 0, max: 2 });
+ _ = set1.insert(ClosedInterval { min: 1, max: 4 });
+ _ = set1.insert(ClosedInterval { min: 20, max: 22 });
+ _ = set1.insert(ClosedInterval { min: 25, max: 26 });
+ _ = set1.insert(ClosedInterval { min: 26, max: 27 });
+ let mut set2 = SupersetSet::new();
+ _ = set2.insert(ClosedInterval { min: 10, max: 12 });
+ _ = set2.insert(ClosedInterval { min: 14, max: 16 });
+ _ = set2.insert(ClosedInterval { min: 0, max: 3 });
+ _ = set2.insert(ClosedInterval { min: 3, max: 4 });
+ _ = set2.insert(ClosedInterval { min: 23, max: 25 });
+ _ = set2.insert(ClosedInterval { min: 25, max: 27 });
+ let mut union = set1.union(&set2);
+ assert!(union.next() == Some(&ClosedInterval { min: 0, max: 3 }));
+ assert!(union.next() == Some(&ClosedInterval { min: 1, max: 4 }));
+ assert!(union.next() == Some(&ClosedInterval { min: 10, max: 12 }));
+ assert!(union.next() == Some(&ClosedInterval { min: 14, max: 19 }));
+ assert!(union.next() == Some(&ClosedInterval { min: 20, max: 22 }));
+ assert!(union.next() == Some(&ClosedInterval { min: 23, max: 25 }));
+ assert!(union.next() == Some(&ClosedInterval { min: 25, max: 27 }));
+ assert!(union.next().is_none());
+ assert!(union.next().is_none());
+ assert!(union.next().is_none());
+}
+#[test]
+fn intersection() {
+ let mut set1 = SupersetSet::new();
+ _ = set1.insert(ClosedInterval { min: 14, max: 19 });
+ _ = set1.insert(ClosedInterval { min: 10, max: 12 });
+ _ = set1.insert(ClosedInterval { min: 0, max: 3 });
+ _ = set1.insert(ClosedInterval { min: 0, max: 2 });
+ _ = set1.insert(ClosedInterval { min: 1, max: 4 });
+ _ = set1.insert(ClosedInterval { min: 20, max: 22 });
+ _ = set1.insert(ClosedInterval { min: 25, max: 26 });
+ _ = set1.insert(ClosedInterval { min: 26, max: 27 });
+ let mut set2 = SupersetSet::new();
+ _ = set2.insert(ClosedInterval { min: 10, max: 12 });
+ _ = set2.insert(ClosedInterval { min: 14, max: 16 });
+ _ = set2.insert(ClosedInterval { min: 0, max: 3 });
+ _ = set2.insert(ClosedInterval { min: 3, max: 4 });
+ _ = set2.insert(ClosedInterval { min: 23, max: 25 });
+ _ = set2.insert(ClosedInterval { min: 25, max: 27 });
+ let mut intersection = set1.intersection(&set2);
+ assert!(intersection.next() == Some(&ClosedInterval { min: 0, max: 3 }));
+ assert!(intersection.next() == Some(&ClosedInterval { min: 3, max: 4 }));
+ assert!(intersection.next() == Some(&ClosedInterval { min: 10, max: 12 }));
+ assert!(intersection.next() == Some(&ClosedInterval { min: 14, max: 16 }));
+ assert!(intersection.next() == Some(&ClosedInterval { min: 25, max: 26 }));
+ assert!(intersection.next() == Some(&ClosedInterval { min: 26, max: 27 }));
+ assert!(intersection.next().is_none());
+ assert!(intersection.next().is_none());
+ assert!(intersection.next().is_none());
+}
+#[test]
+fn replace() {
+ let mut set = SupersetSet::new();
+ _ = set.insert(ClosedInterval { min: 14, max: 19 });
+ _ = set.insert(ClosedInterval { min: 10, max: 12 });
+ _ = set.insert(ClosedInterval { min: 0, max: 3 });
+ _ = set.insert(ClosedInterval { min: 0, max: 2 });
+ _ = set.insert(ClosedInterval { min: 1, max: 4 });
+ _ = set.insert(ClosedInterval { min: 20, max: 22 });
+ _ = set.insert(ClosedInterval { min: 25, max: 26 });
+ _ = set.insert(ClosedInterval { min: 26, max: 27 });
+ // Does not replace proper supersets.
+ assert!(
+ set.replace(ClosedInterval { min: 20, max: 21 }).is_none()
+ && set.contains(&ClosedInterval { min: 20, max: 22 })
+ && set.contains_proper_superset(&ClosedInterval { min: 20, max: 21 })
+ && !set.contains(&ClosedInterval { min: 20, max: 21 })
+ );
+ // Successful replace.
+ assert!(
+ set.replace(ClosedInterval { min: 0, max: 3 }) == Some(ClosedInterval { min: 0, max: 3 })
+ && set.contains(&ClosedInterval { min: 0, max: 3 })
+ );
+ // Replace is just an insert when a superset does not exist.
+ assert!(
+ set.replace(ClosedInterval { min: 100, max: 300 }).is_none()
+ && set.contains(&ClosedInterval { min: 100, max: 300 })
+ );
+}
+#[expect(clippy::zero_sized_map_values, reason = "set is defined as it")]
+#[ignore = "silence lint"]
+#[test]
+fn range() {
+ _ = Range {
+ iter: BTreeMap::<u32, ()>::new().range(..),
+ };
+}