Skip to main content

frozen_collections_core/traits/
set_ops.rs

1use crate::sets::{Difference, Intersection, SymmetricDifference, Union};
2use crate::traits::Set;
3
4/// Common operations on sets.
5pub trait SetOps<T> {
6    /// Visits the values representing the union,
7    /// i.e., all the values in `self` or `other`, without duplicates.
8    #[must_use]
9    fn union<'a, ST>(&'a self, other: &'a ST) -> Union<'a, Self, ST, T>
10    where
11        ST: Set<T>,
12        Self: Sized + Set<T>,
13    {
14        Union::new(self, other)
15    }
16
17    /// Visits the values representing the symmetric difference,
18    /// i.e., the values that are in `self` or in `other` but not in both.
19    #[must_use]
20    fn symmetric_difference<'a, ST>(&'a self, other: &'a ST) -> SymmetricDifference<'a, Self, ST, T>
21    where
22        ST: Set<T>,
23        Self: Sized + Set<T>,
24    {
25        SymmetricDifference::new(self, other)
26    }
27
28    /// Visits the values representing the difference,
29    /// i.e., the values that are in `self` but not in `other`.
30    #[must_use]
31    fn difference<'a, ST>(&'a self, other: &'a ST) -> Difference<'a, Self, ST, T>
32    where
33        ST: Set<T>,
34        Self: Sized + Set<T>,
35    {
36        Difference::new(self, other)
37    }
38
39    /// Visits the values representing the intersection,
40    /// i.e., the values that are both in `self` and `other`.
41    ///
42    /// When an equal element is present in `self` and `other`,
43    /// then the resulting `Intersection` may yield references to
44    /// one or the other. This can be relevant if `T` contains fields which
45    /// are not compared by its `Eq` implementation and may hold different
46    /// values between the two equal copies of `T` in the two sets.
47    #[must_use]
48    fn intersection<'a, ST>(&'a self, other: &'a ST) -> Intersection<'a, Self, ST, T>
49    where
50        ST: Set<T>,
51        Self: Sized + Set<T>,
52    {
53        Intersection::new(self, other)
54    }
55
56    /// Returns `true` if `self` has no entries in common with `other`.
57    /// This is equivalent to checking for an empty intersection.
58    #[must_use]
59    #[mutants::skip]
60    fn is_disjoint<'a, ST>(&'a self, other: &'a ST) -> bool
61    where
62        ST: Set<T>,
63        Self: Sized + Set<T>,
64    {
65        if self.len() <= other.len() {
66            self.iter().all(|v| !other.contains(v))
67        } else {
68            other.iter().all(|v| !self.contains(v))
69        }
70    }
71
72    /// Returns `true` if the set is a subset of another,
73    /// i.e., `other` contains at least all the values in `self`.
74    #[must_use]
75    fn is_subset<'a, ST>(&'a self, other: &'a ST) -> bool
76    where
77        ST: Set<T>,
78        Self: Sized + Set<T>,
79    {
80        if self.len() <= other.len() {
81            self.iter().all(|v| other.contains(v))
82        } else {
83            false
84        }
85    }
86
87    /// Returns `true` if the set is a superset of another,
88    /// i.e., `self` contains at least all the values in `other`.
89    #[must_use]
90    fn is_superset<'a, ST>(&'a self, other: &'a ST) -> bool
91    where
92        ST: Set<T>,
93        Self: Sized + Set<T>,
94    {
95        if other.len() <= self.len() {
96            other.iter().all(|v| self.contains(v))
97        } else {
98            false
99        }
100    }
101}
102
103impl<ST, T> SetOps<T> for ST where ST: Set<T> {}