1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
//! [![git]](https://git.philomathiclife.com/superset_map/log.html) [![crates-io]](https://crates.io/crates/superset_map) [![docs-rs]](crate)
//!
//! [git]: https://git.philomathiclife.com/git_badge.svg
//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
//!
//! `superset_map` is a library for [`Set`]s that have an order defined on them. Its 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`].
//!
//! Nightly Rust is required. Once
//! [`BTreeMap` cursors are stabilized](https://github.com/rust-lang/rust/issues/107540), stable Rust will work.
//!
//! ## Example
//!
//! ```
//! # use core::{borrow::Borrow, cmp::Ordering};
//! # use superset_map::{zfc::{num_bigint::BigUint, BoundedCardinality, Cardinality, Set}, SetOrd, SupersetSet};
//! #[derive(Clone, Copy, Eq, PartialEq)]
//! struct ShortAscii<'a> {
//! val: &'a [u8],
//! }
//! impl<'a> ShortAscii<'a> {
//! fn new(val: &'a [u8]) -> Option<ShortAscii<'a>> {
//! (val.len() <= 255 && val.is_ascii()).then_some(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 is_plain(self) -> bool {
//! match self {
//! WildcardAscii::Plain(_) => true,
//! WildcardAscii::Wildcard(_) => false,
//! }
//! }
//! const fn is_wildcard(self) -> bool {
//! !self.is_plain()
//! }
//! }
//! impl<'a> PartialOrd<Self> for WildcardAscii<'a> {
//! fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
//! 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.is_wildcard() {
//! if other.is_wildcard() {
//! self.val().len().cmp(&other.val().len()).reverse()
//! } else {
//! Ordering::Greater
//! }
//! } else if other.is_wildcard() {
//! 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 bounded_cardinality(&self) -> BoundedCardinality {
//! BoundedCardinality::new_exact(self.cardinality().unwrap())
//! }
//! fn cardinality(&self) -> Option<Cardinality> {
//! 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<Q>(&self, elem: &Q) -> bool
//! where
//! Q: Borrow<Self::Elem> + 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 is_proper_subset(&self, val: &Self) -> bool {
//! val.is_wildcard()
//! && match val.val().len().cmp(&self.val().len()) {
//! Ordering::Less => val.val().val == &self.val().val[..val.val().len() as usize],
//! Ordering::Equal => self.is_plain() && self.val() == val.val(),
//! Ordering::Greater => false,
//! }
//! }
//! fn is_subset(&self, val: &Self) -> bool {
//! self == val || self.is_proper_subset(val)
//! }
//! }
//! impl<'a> SetOrd for WildcardAscii<'a> {}
//! 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.into_iter();
//! assert!(iter.next().map_or(false, |s| s
//! == WildcardAscii::Wildcard(ShortAscii::new(b"b").unwrap())));
//! assert!(iter.next().map_or(false, |s| s
//! == WildcardAscii::Plain(ShortAscii::new(b"foo").unwrap())));
//! assert!(iter.next().is_none());
//! ```
extern crate alloc;
use BTreeMap;
use RangeBounds;
pub use zfc;
use Set;
/// A map of keys and values where the keys implement [`SetOrd`]. The map is backed by a B-tree.
/// A set of values where the values implement [`SetOrd`]. The set is backed by a B-tree.
pub use SupersetMap;
pub use SupersetSet;
/// Must conform to the following properties ∀`a`, `b`, `c`: `Self`:
/// * `a.is_subset(b)` ⇒ `a <= b`.
/// * `a.is_subset(b) && !(a.is_subset(c) || c.is_subset(b))` ⇒ `c` `<` `a` `<=` `b` ∨ `a` `<=` `b` `<` `c`.
///
/// In American English prose, the above simply states that one only need to check for the "next" element of `a`
/// in an ordered sequence of `Self`s to determine if there exists any superset of `a` in the entire sequence beside
/// `a` itself. Put in a different way, the "distance" between a set and a proper supserset is "less" than the "distance"
/// between the same set and a non-superset that is greater.