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
166
167
168
169
170
171
172
173
//! # `superset_map`
//!
//! `superset_map` is a library for [`Set`]s that have an order defined on them.
//! It's main data structure is [`SupersetMap`] which is a specialized version of
//! [`BTreeMap`](https://doc.rust-lang.org/alloc/collections/btree_map/struct.BTreeMap.html)
//! where only supersets are stored. This can be useful when the keys don't fit well or at all with the concept of
//! [`RangeBounds`](https://doc.rust-lang.org/stable/core/ops/trait.RangeBounds.html).
//!
//! Version `1.69.0` or newer of nightly `rustc` is required. Once
//! [`BTreeMap` cursors are stabilized](https://github.com/rust-lang/rust/issues/107540), stable `rustc` will work.
//!
//! ## Example
//!
//! ```rust
//! use core::borrow::Borrow;
//! use core::cmp::Ordering;
//! use num_bigint::BigUint;
//! use superset_map::{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<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> {}
//! 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.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());
//! }
//! ```
#![no_std]
#![feature(btree_cursors)]
#![deny(
    unsafe_code,
    unused,
    warnings,
    clippy::all,
    clippy::cargo,
    clippy::complexity,
    clippy::correctness,
    clippy::nursery,
    clippy::pedantic,
    clippy::perf,
    clippy::restriction,
    clippy::style,
    clippy::suspicious
)]
#![allow(
    clippy::blanket_clippy_restriction_lints,
    clippy::needless_doctest_main,
    clippy::pub_use
)]
use zfc::Set;
/// A map of keys and values where the keys implement [`SetOrd`]. The map is backed by a B-tree.
pub mod superset_map;
/// A set of values where the values implement [`SetOrd`]. The set is backed by a B-tree.
pub mod superset_set;
pub use superset_map::SupersetMap;
pub use superset_set::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.
pub trait SetOrd: Ord + Set {}