superset_map

superset_map is a library for Sets that have an order defined on them. It's main data structure is SupersetMap which is a specialized version of BTreeMap where only supersets are stored. This can be useful when the keys don't fit well or at all with the concept of RangeBounds.

Example

```rust use core::borrow::Borrow; use core::cmp::Ordering; use numbigint::BigUint; use supersetmap::{SetOrd, SupersetSet}; use zfc::{BoundedCardinality, Cardinality, Set};

[derive(Clone, Copy, Eq, PartialEq)]

struct ShortAscii<'a> { val: &'a [u8], } impl<'a> ShortAscii<'a> { fn new(val: &'a [u8]) -> Option> { (val.len() <= 255 && val.isascii()).thensome(Self { val }) } fn len(self) -> u8 { self.val.len().try_into().expect("The ShortAscii instance was not constructed properly and contains more than 255 bytes.") } }

[derive(Clone, Copy, Eq, PartialEq)]

enum WildcardAscii<'a> { Plain(ShortAscii<'a>), // Represents a ShortAscii<'a> with an implicit wildcard at the end // meaning it's all ShortAscii<'a>s that begin with the contained ShortAscii<'a>.val. Wildcard(ShortAscii<'a>), } impl<'a> WildcardAscii<'a> { const fn val(self) -> ShortAscii<'a> { match self { WildcardAscii::Plain(s) | WildcardAscii::Wildcard(s) => s, } } const fn isplain(self) -> bool { match self { WildcardAscii::Plain() => true, WildcardAscii::Wildcard() => false, } } const fn iswildcard(self) -> bool { !self.isplain() } } impl<'a> PartialOrd for WildcardAscii<'a> { fn partialcmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl<'a> Ord for WildcardAscii<'a> { fn cmp(&self, other: &Self) -> Ordering { let len = u8::min(self.val().len(), other.val().len()) as usize; match self.val().val[..len].cmp(&other.val().val[..len]) { Ordering::Less => Ordering::Less, Ordering::Equal => { if self.iswildcard() { if other.iswildcard() { self.val().len().cmp(&other.val().len()).reverse() } else { Ordering::Greater } } else if other.iswildcard() { Ordering::Less } else { self.val().len().cmp(&other.val().len()) } } Ordering::Greater => Ordering::Greater, } } } impl<'a> Set for WildcardAscii<'a> { type Elem = ShortAscii<'a>; fn boundedcardinality(&self) -> BoundedCardinality { BoundedCardinality::newexact(self.cardinality().unwrap()) } fn cardinality(&self) -> Option { Some(Cardinality::Finite(match *self { WildcardAscii::Plain() => BigUint::new(vec![1]), // Geometric series. WildcardAscii::Wildcard(v) => { (BigUint::new(vec![128]).pow((u8::MAX - v.len()) as u32 + 1) - BigUint::new(vec![1])) / BigUint::new(vec![127]) } })) } fn contains(&self, elem: &Q) -> bool where Q: Borrow + Eq + ?Sized, { match *self { WildcardAscii::Plain(v) => v == *elem.borrow(), WildcardAscii::Wildcard(v) => { v.len() <= elem.borrow().len() && *v.val == elem.borrow().val[..v.len() as usize] } } } fn ispropersubset(&self, val: &Self) -> bool { val.iswildcard() && match val.val().len().cmp(&self.val().len()) { Ordering::Less => val.val().val == &self.val().val[..val.val().len() as usize], Ordering::Equal => self.isplain() && self.val() == val.val(), Ordering::Greater => false, } } fn issubset(&self, val: &Self) -> bool { self == val || self.ispropersubset(val) } } impl<'a> SetOrd for WildcardAscii<'a> {} fn main() { let mut set = SupersetSet::new(); set.insert(WildcardAscii::Plain(ShortAscii::new(b"foo").unwrap())); set.insert(WildcardAscii::Plain(ShortAscii::new(b"bar").unwrap())); set.insert(WildcardAscii::Wildcard(ShortAscii::new(b"b").unwrap())); set.insert(WildcardAscii::Wildcard(ShortAscii::new(b"bar").unwrap())); let mut iter = set.intoiter(); assert!(iter.next().mapor(false, |s| s == WildcardAscii::Wildcard(ShortAscii::new(b"b").unwrap()))); assert!(iter.next().mapor(false, |s| s == WildcardAscii::Plain(ShortAscii::new(b"foo").unwrap()))); assert!(iter.next().is_none()); } ```

Status

This package will be actively maintained until it is deemed “feature complete”.

The crates are only tested on the x86_64-unknown-linux-gnu and x86_64-unknown-openbsd targets, but they should work on any Tier 1 with Host Tools target.

Version 1.69.0 or newer of nightly rustc is required. Once BTreeMap cursors are stablilized, stable rustc will work.