Skip to main content

nonempty_collections/
btree_set.rs

1//! Non-empty [`BTreeSet`]s.
2
3use core::fmt;
4use std::borrow::Borrow;
5use std::collections::BTreeSet;
6use std::num::NonZeroUsize;
7
8#[cfg(feature = "serde")]
9use serde::Deserialize;
10#[cfg(feature = "serde")]
11use serde::Serialize;
12
13use crate::iter::NonEmptyIterator;
14use crate::FromNonEmptyIterator;
15use crate::IntoIteratorExt;
16use crate::IntoNonEmptyIterator;
17use crate::Singleton;
18
19/// Like the [`crate::nes!`] macro, but for Binary Tree Sets.
20///
21/// ```
22/// use nonempty_collections::nebts;
23///
24/// let s = nebts![1, 2, 2, 3,];
25/// assert_eq!(3, s.len().get());
26/// ```
27#[macro_export]
28macro_rules! nebts {
29    ($h:expr, $( $x:expr ),* $(,)?) => {{
30        let mut set = $crate::NEBTreeSet::new($h);
31        $( set.insert($x); )*
32        set
33    }};
34    ($h:expr) => {
35        $crate::NEBTreeSet::new($h)
36    }
37}
38
39/// A non-empty, growable `BTreeSet`.
40///
41/// # Construction and Access
42///
43/// The [`nebts`] macro is the simplest way to construct an `NEBTreeSet`:
44///
45/// ```
46/// use nonempty_collections::*;
47///
48/// let s = nebts![1, 1, 2, 2, 3, 3, 4, 4];
49/// let mut v: NEVec<_> = s.nonempty_iter().collect();
50/// v.sort();
51/// assert_eq!(nev![&1, &2, &3, &4], v);
52/// ```
53///
54/// ```
55/// use nonempty_collections::nebts;
56///
57/// let s = nebts!["Fëanor", "Fingolfin", "Finarfin"];
58/// assert!(s.contains(&"Fëanor"));
59/// ```
60///
61/// # Conversion
62///
63/// If you have a [`BTreeSet`] but want an `NEBTreeSet`, try [`NEBTreeSet::try_from_set`].
64/// Naturally, this might not succeed.
65///
66/// If you have an `NEBTreeSet` but want a `BTreeSet`, try their corresponding
67/// [`From`] instance. This will always succeed.
68///
69/// ```
70/// use std::collections::BTreeSet;
71///
72/// use nonempty_collections::nebts;
73///
74/// let n0 = nebts![1, 2, 3];
75/// let s0 = BTreeSet::from(n0);
76///
77/// // Or just use `Into`.
78/// let n1 = nebts![1, 2, 3];
79/// let s1: BTreeSet<_> = n1.into();
80/// ```
81///
82/// # API Differences with [`BTreeSet`]
83///
84/// Note that the following methods aren't implemented for `NEBTreeSet`:
85///
86/// - `clear`
87/// - `remove`
88/// - `retain`
89/// - `take`
90///
91/// As these methods are all "mutate-in-place" style and are difficult to
92/// reconcile with the non-emptiness guarantee.
93#[allow(clippy::unsafe_derive_deserialize)]
94#[cfg_attr(
95    feature = "serde",
96    derive(Serialize, Deserialize),
97    serde(bound(
98        serialize = "T: Ord + Clone + Serialize",
99        deserialize = "T: Ord + Deserialize<'de>"
100    )),
101    serde(into = "BTreeSet<T>", try_from = "BTreeSet<T>")
102)]
103#[derive(Clone)]
104pub struct NEBTreeSet<T> {
105    inner: BTreeSet<T>,
106}
107
108impl<T> NEBTreeSet<T>
109where
110    T: Ord,
111{
112    /// Creates a new `NEBTreeSet` with a single element.
113    #[must_use]
114    pub fn new(value: T) -> Self {
115        let mut inner = BTreeSet::new();
116        inner.insert(value);
117        Self { inner }
118    }
119
120    /// Returns a regular iterator over the values in this non-empty set.
121    ///
122    /// For a `NonEmptyIterator` see `Self::nonempty_iter()`.
123    pub fn iter(&self) -> std::collections::btree_set::Iter<'_, T> {
124        self.inner.iter()
125    }
126
127    /// An iterator visiting all elements in arbitrary order.
128    pub fn nonempty_iter(&self) -> Iter<'_, T> {
129        Iter {
130            iter: self.inner.iter(),
131        }
132    }
133
134    /// Returns the number of elements in the set. Always 1 or more.
135    ///
136    /// ```
137    /// use nonempty_collections::nebts;
138    ///
139    /// let s = nebts![1, 2, 3];
140    /// assert_eq!(3, s.len().get());
141    /// ```
142    #[must_use]
143    pub fn len(&self) -> NonZeroUsize {
144        unsafe { NonZeroUsize::new_unchecked(self.inner.len()) }
145    }
146
147    /// Attempt a conversion from a [`BTreeSet`], consuming the given `BTreeSet`.
148    /// Will return `None` if the `BTreeSet` is empty.
149    ///
150    /// ```
151    /// use std::collections::BTreeSet;
152    ///
153    /// use nonempty_collections::nebts;
154    /// use nonempty_collections::NEBTreeSet;
155    ///
156    /// let mut s = BTreeSet::new();
157    /// s.extend([1, 2, 3]);
158    ///
159    /// let n = NEBTreeSet::try_from_set(s);
160    /// assert_eq!(Some(nebts![1, 2, 3]), n);
161    /// let s: BTreeSet<()> = BTreeSet::new();
162    /// assert_eq!(None, NEBTreeSet::try_from_set(s));
163    /// ```
164    #[must_use]
165    pub fn try_from_set(set: BTreeSet<T>) -> Option<NEBTreeSet<T>> {
166        if set.is_empty() {
167            None
168        } else {
169            Some(NEBTreeSet { inner: set })
170        }
171    }
172
173    /// Returns true if the set contains a value.
174    ///
175    /// ```
176    /// use nonempty_collections::nebts;
177    ///
178    /// let s = nebts![1, 2, 3];
179    /// assert!(s.contains(&3));
180    /// assert!(!s.contains(&10));
181    /// ```
182    #[must_use]
183    pub fn contains<Q>(&self, value: &Q) -> bool
184    where
185        T: Ord + Borrow<Q>,
186        Q: Ord + ?Sized,
187    {
188        self.inner.contains(value)
189    }
190
191    /// Visits the values representing the difference, i.e., the values that are
192    /// in `self` but not in `other`.
193    ///
194    /// ```
195    /// use nonempty_collections::nebts;
196    ///
197    /// let s0 = nebts![1, 2, 3];
198    /// let s1 = nebts![3, 4, 5];
199    /// let mut v: Vec<_> = s0.difference(&s1).collect();
200    /// v.sort();
201    /// assert_eq!(vec![&1, &2], v);
202    /// ```
203    pub fn difference<'a>(
204        &'a self,
205        other: &'a NEBTreeSet<T>,
206    ) -> std::collections::btree_set::Difference<'a, T> {
207        self.inner.difference(&other.inner)
208    }
209
210    /// Returns a reference to the value in the set, if any, that is equal to
211    /// the given value.
212    ///
213    /// The value may be any borrowed form of the set’s value type, but `Hash`
214    /// and `Eq` on the borrowed form must match those for the value type.
215    ///
216    /// ```
217    /// use nonempty_collections::nebts;
218    ///
219    /// let s = nebts![1, 2, 3];
220    /// assert_eq!(Some(&3), s.get(&3));
221    /// assert_eq!(None, s.get(&10));
222    /// ```
223    #[must_use]
224    pub fn get<Q>(&self, value: &Q) -> Option<&T>
225    where
226        T: Ord + Borrow<Q>,
227        Q: Ord,
228    {
229        self.inner.get(value)
230    }
231
232    /// Adds a value to the set.
233    ///
234    /// If the set did not have this value present, `true` is returned.
235    ///
236    /// If the set did have this value present, `false` is returned.
237    ///
238    /// ```
239    /// use nonempty_collections::nebts;
240    ///
241    /// let mut s = nebts![1, 2, 3];
242    /// assert_eq!(false, s.insert(2));
243    /// assert_eq!(true, s.insert(4));
244    /// ```
245    pub fn insert(&mut self, value: T) -> bool {
246        self.inner.insert(value)
247    }
248
249    /// Visits the values representing the interesection, i.e., the values that
250    /// are both in `self` and `other`.
251    ///
252    /// ```
253    /// use nonempty_collections::nebts;
254    ///
255    /// let s0 = nebts![1, 2, 3];
256    /// let s1 = nebts![3, 4, 5];
257    /// let mut v: Vec<_> = s0.intersection(&s1).collect();
258    /// v.sort();
259    /// assert_eq!(vec![&3], v);
260    /// ```
261    pub fn intersection<'a>(
262        &'a self,
263        other: &'a NEBTreeSet<T>,
264    ) -> std::collections::btree_set::Intersection<'a, T> {
265        self.inner.intersection(&other.inner)
266    }
267
268    /// Returns `true` if `self` has no elements in common with `other`.
269    /// This is equivalent to checking for an empty intersection.
270    ///
271    /// ```
272    /// use nonempty_collections::nebts;
273    ///
274    /// let s0 = nebts![1, 2, 3];
275    /// let s1 = nebts![4, 5, 6];
276    /// assert!(s0.is_disjoint(&s1));
277    /// ```
278    #[must_use]
279    pub fn is_disjoint(&self, other: &NEBTreeSet<T>) -> bool {
280        self.inner.is_disjoint(&other.inner)
281    }
282
283    /// Returns `true` if the set is a subset of another, i.e., `other` contains
284    /// at least all the values in `self`.
285    ///
286    /// ```
287    /// use nonempty_collections::nebts;
288    ///
289    /// let sub = nebts![1, 2, 3];
290    /// let sup = nebts![1, 2, 3, 4];
291    ///
292    /// assert!(sub.is_subset(&sup));
293    /// assert!(!sup.is_subset(&sub));
294    /// ```
295    #[must_use]
296    pub fn is_subset(&self, other: &NEBTreeSet<T>) -> bool {
297        self.inner.is_subset(&other.inner)
298    }
299
300    /// Returns `true` if the set is a superset of another, i.e., `self`
301    /// contains at least all the values in `other`.
302    ///
303    /// ```
304    /// use nonempty_collections::nebts;
305    ///
306    /// let sub = nebts![1, 2, 3];
307    /// let sup = nebts![1, 2, 3, 4];
308    ///
309    /// assert!(sup.is_superset(&sub));
310    /// assert!(!sub.is_superset(&sup));
311    /// ```
312    #[must_use]
313    pub fn is_superset(&self, other: &NEBTreeSet<T>) -> bool {
314        self.inner.is_superset(&other.inner)
315    }
316
317    /// Adds a value to the set, replacing the existing value, if any, that is
318    /// equal to the given one. Returns the replaced value.
319    pub fn replace(&mut self, value: T) -> Option<T> {
320        self.inner.replace(value)
321    }
322
323    /// Visits the values representing the union, i.e., all the values in `self`
324    /// or `other`, without duplicates.
325    ///
326    /// Note that a Union is always non-empty.
327    ///
328    /// ```
329    /// use nonempty_collections::*;
330    ///
331    /// let s0 = nebts![1, 2, 3];
332    /// let s1 = nebts![3, 4, 5];
333    /// let mut v: NEVec<_> = s0.union(&s1).collect();
334    /// v.sort();
335    /// assert_eq!(nev![&1, &2, &3, &4, &5], v);
336    /// ```
337    pub fn union<'a>(&'a self, other: &'a NEBTreeSet<T>) -> Union<'a, T> {
338        Union {
339            inner: self.inner.union(&other.inner),
340        }
341    }
342}
343
344impl<T> AsRef<BTreeSet<T>> for NEBTreeSet<T> {
345    fn as_ref(&self) -> &BTreeSet<T> {
346        &self.inner
347    }
348}
349
350impl<T> AsMut<BTreeSet<T>> for NEBTreeSet<T> {
351    fn as_mut(&mut self) -> &mut BTreeSet<T> {
352        &mut self.inner
353    }
354}
355
356impl<T> PartialEq for NEBTreeSet<T>
357where
358    T: Ord,
359{
360    /// ```
361    /// use nonempty_collections::nebts;
362    ///
363    /// let s0 = nebts![1, 2, 3];
364    /// let s1 = nebts![1, 2, 3];
365    /// let s2 = nebts![1, 2];
366    /// let s3 = nebts![1, 2, 3, 4];
367    ///
368    /// assert!(s0 == s1);
369    /// assert!(s0 != s2);
370    /// assert!(s0 != s3);
371    /// ```
372    fn eq(&self, other: &Self) -> bool {
373        self.len() == other.len() && self.intersection(other).count() == self.len().get()
374    }
375}
376
377impl<T> Eq for NEBTreeSet<T> where T: Ord {}
378
379impl<T> IntoNonEmptyIterator for NEBTreeSet<T> {
380    type IntoNEIter = IntoIter<T>;
381
382    fn into_nonempty_iter(self) -> Self::IntoNEIter {
383        IntoIter {
384            iter: self.inner.into_iter(),
385        }
386    }
387}
388
389impl<'a, T> IntoNonEmptyIterator for &'a NEBTreeSet<T>
390where
391    T: Ord,
392{
393    type IntoNEIter = Iter<'a, T>;
394
395    fn into_nonempty_iter(self) -> Self::IntoNEIter {
396        self.nonempty_iter()
397    }
398}
399
400impl<T> IntoIterator for NEBTreeSet<T> {
401    type Item = T;
402
403    type IntoIter = std::collections::btree_set::IntoIter<T>;
404
405    fn into_iter(self) -> Self::IntoIter {
406        self.inner.into_iter()
407    }
408}
409
410impl<'a, T> IntoIterator for &'a NEBTreeSet<T>
411where
412    T: Ord,
413{
414    type Item = &'a T;
415
416    type IntoIter = std::collections::btree_set::Iter<'a, T>;
417
418    fn into_iter(self) -> Self::IntoIter {
419        self.iter()
420    }
421}
422
423/// ```
424/// use nonempty_collections::*;
425///
426/// let s0 = nebts![1, 2, 3];
427/// let s1: NEBTreeSet<_> = s0.nonempty_iter().cloned().collect();
428/// assert_eq!(s0, s1);
429/// ```
430impl<T> FromNonEmptyIterator<T> for NEBTreeSet<T>
431where
432    T: Ord,
433{
434    /// ```
435    /// use nonempty_collections::*;
436    ///
437    /// let v = nev![1, 1, 2, 3, 2];
438    /// let s = NEBTreeSet::from_nonempty_iter(v);
439    ///
440    /// assert_eq!(nebts![1, 2, 3], s);
441    /// ```
442    fn from_nonempty_iter<I>(iter: I) -> Self
443    where
444        I: IntoNonEmptyIterator<Item = T>,
445    {
446        NEBTreeSet {
447            inner: iter.into_nonempty_iter().into_iter().collect(),
448        }
449    }
450}
451
452/// A non-empty iterator over the values of an [`NEBTreeSet`].
453#[must_use = "non-empty iterators are lazy and do nothing unless consumed"]
454pub struct Iter<'a, T: 'a> {
455    iter: std::collections::btree_set::Iter<'a, T>,
456}
457
458impl<'a, T: 'a> IntoIterator for Iter<'a, T> {
459    type Item = &'a T;
460
461    type IntoIter = std::collections::btree_set::Iter<'a, T>;
462
463    fn into_iter(self) -> Self::IntoIter {
464        self.iter
465    }
466}
467
468impl<T> NonEmptyIterator for Iter<'_, T> {}
469
470impl<T: fmt::Debug> fmt::Debug for Iter<'_, T> {
471    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
472        self.iter.fmt(f)
473    }
474}
475
476/// An owned non-empty iterator over the values of an [`NEBTreeSet`].
477#[must_use = "non-empty iterators are lazy and do nothing unless consumed"]
478pub struct IntoIter<T> {
479    iter: std::collections::btree_set::IntoIter<T>,
480}
481
482impl<T> IntoIterator for IntoIter<T> {
483    type Item = T;
484
485    type IntoIter = std::collections::btree_set::IntoIter<T>;
486
487    fn into_iter(self) -> Self::IntoIter {
488        self.iter
489    }
490}
491
492impl<T> NonEmptyIterator for IntoIter<T> {}
493
494impl<T: fmt::Debug> fmt::Debug for IntoIter<T> {
495    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
496        self.iter.fmt(f)
497    }
498}
499
500/// A non-empty iterator producing elements in the union of two [`NEBTreeSet`]s.
501#[must_use = "non-empty iterators are lazy and do nothing unless consumed"]
502pub struct Union<'a, T: 'a> {
503    inner: std::collections::btree_set::Union<'a, T>,
504}
505
506impl<'a, T> IntoIterator for Union<'a, T>
507where
508    T: Ord,
509{
510    type Item = &'a T;
511
512    type IntoIter = std::collections::btree_set::Union<'a, T>;
513
514    fn into_iter(self) -> Self::IntoIter {
515        self.inner
516    }
517}
518
519impl<T> NonEmptyIterator for Union<'_, T> where T: Ord {}
520
521impl<T> fmt::Debug for Union<'_, T>
522where
523    T: fmt::Debug + Ord,
524{
525    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
526        self.inner.fmt(f)
527    }
528}
529
530impl<T> From<NEBTreeSet<T>> for BTreeSet<T>
531where
532    T: Ord,
533{
534    /// ```
535    /// use std::collections::BTreeSet;
536    ///
537    /// use nonempty_collections::nebts;
538    ///
539    /// let s: BTreeSet<_> = nebts![1, 2, 3].into();
540    /// let mut v: Vec<_> = s.into_iter().collect();
541    /// v.sort();
542    /// assert_eq!(vec![1, 2, 3], v);
543    /// ```
544    fn from(s: NEBTreeSet<T>) -> Self {
545        s.inner
546    }
547}
548
549impl<T: fmt::Debug> fmt::Debug for NEBTreeSet<T> {
550    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
551        self.inner.fmt(f)
552    }
553}
554
555impl<T> TryFrom<BTreeSet<T>> for NEBTreeSet<T>
556where
557    T: Ord,
558{
559    type Error = crate::Error;
560
561    fn try_from(set: BTreeSet<T>) -> Result<Self, Self::Error> {
562        let ne = set
563            .try_into_nonempty_iter()
564            .ok_or(crate::Error::Empty)?
565            .collect();
566
567        Ok(ne)
568    }
569}
570
571impl<T> Singleton for NEBTreeSet<T>
572where
573    T: Ord,
574{
575    type Item = T;
576
577    /// ```
578    /// use nonempty_collections::{NEBTreeSet, Singleton, nebts};
579    ///
580    /// let s = NEBTreeSet::singleton(1);
581    /// assert_eq!(nebts![1], s);
582    /// ```
583    fn singleton(item: Self::Item) -> Self {
584        NEBTreeSet::new(item)
585    }
586}
587
588impl<T> Extend<T> for NEBTreeSet<T>
589where
590    T: Ord,
591{
592    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
593        self.inner.extend(iter);
594    }
595}
596
597#[cfg(test)]
598mod test {
599    use maplit::btreeset;
600
601    #[test]
602    fn debug_impl() {
603        let expected = format!("{:?}", btreeset! {0});
604        let actual = format!("{:?}", nebts! {0});
605        assert_eq!(expected, actual);
606    }
607
608    #[test]
609    fn iter_debug_impl() {
610        let expected = format!("{:?}", btreeset! {0}.iter());
611        let actual = format!("{:?}", nebts! {0}.nonempty_iter());
612        assert_eq!(expected, actual);
613    }
614}
615
616#[cfg(feature = "serde")]
617#[cfg(test)]
618mod serde_tests {
619    use crate::NEBTreeSet;
620    use std::collections::BTreeSet;
621
622    #[test]
623    fn json() {
624        let set0 = nebts![1, 1, 2, 3, 2, 1, 4];
625        let j = serde_json::to_string(&set0).unwrap();
626        let set1 = serde_json::from_str(&j).unwrap();
627        assert_eq!(set0, set1);
628
629        let empty: BTreeSet<usize> = BTreeSet::new();
630        let j = serde_json::to_string(&empty).unwrap();
631        let bad = serde_json::from_str::<NEBTreeSet<usize>>(&j);
632        assert!(bad.is_err());
633    }
634}