Skip to main content

nonempty_collections/
set.rs

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