nonempty_collections/
set.rs

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