phf/
ordered_set.rs

1//! An order-preserving immutable set constructed at compile time.
2use crate::{ordered_map, OrderedMap, PhfHash};
3use core::fmt;
4use core::iter::FusedIterator;
5use core::iter::IntoIterator;
6use phf_shared::PhfBorrow;
7
8/// An order-preserving immutable set constructed at compile time.
9///
10/// Unlike a `Set`, iteration order is guaranteed to match the definition
11/// order.
12///
13/// ## Note
14///
15/// The fields of this struct are public so that they may be initialized by the
16/// `phf_ordered_set!` macro and code generation. They are subject to change at
17/// any time and should never be accessed directly.
18pub struct OrderedSet<T: 'static> {
19    #[doc(hidden)]
20    pub map: OrderedMap<T, ()>,
21}
22
23impl<T> fmt::Debug for OrderedSet<T>
24where
25    T: fmt::Debug,
26{
27    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
28        fmt.debug_set().entries(self).finish()
29    }
30}
31
32impl<T> PartialEq for OrderedSet<T>
33where
34    T: PartialEq,
35{
36    fn eq(&self, other: &Self) -> bool {
37        self.map == other.map
38    }
39}
40
41impl<T> Eq for OrderedSet<T> where T: Eq {}
42
43impl<T> OrderedSet<T> {
44    /// Returns the number of elements in the `OrderedSet`.
45    #[inline]
46    pub const fn len(&self) -> usize {
47        self.map.len()
48    }
49
50    /// Returns true if the `OrderedSet` contains no elements.
51    #[inline]
52    pub const fn is_empty(&self) -> bool {
53        self.len() == 0
54    }
55
56    /// Returns a reference to the set's internal static instance of the given
57    /// key.
58    ///
59    /// This can be useful for interning schemes.
60    pub fn get_key<U: ?Sized>(&self, key: &U) -> Option<&T>
61    where
62        U: Eq + PhfHash,
63        T: PhfBorrow<U>,
64    {
65        self.map.get_key(key)
66    }
67
68    /// Returns the index of the key within the list used to initialize
69    /// the ordered set.
70    pub fn get_index<U: ?Sized>(&self, key: &U) -> Option<usize>
71    where
72        U: Eq + PhfHash,
73        T: PhfBorrow<U>,
74    {
75        self.map.get_index(key)
76    }
77
78    /// Returns a reference to the key at an index
79    /// within the list used to initialize the ordered set. See `.get_index(key)`.
80    pub fn index(&self, index: usize) -> Option<&T> {
81        self.map.index(index).map(|(k, &())| k)
82    }
83
84    /// Returns true if `value` is in the `OrderedSet`.
85    pub fn contains<U: ?Sized>(&self, value: &U) -> bool
86    where
87        U: Eq + PhfHash,
88        T: PhfBorrow<U>,
89    {
90        self.map.contains_key(value)
91    }
92
93    /// Returns an iterator over the values in the set.
94    ///
95    /// Values are returned in the same order in which they were defined.
96    pub fn iter(&self) -> Iter<'_, T> {
97        Iter {
98            iter: self.map.keys(),
99        }
100    }
101}
102
103impl<T> OrderedSet<T>
104where
105    T: Eq + PhfHash + PhfBorrow<T>,
106{
107    /// Returns true if `other` shares no elements with `self`.
108    #[inline]
109    pub fn is_disjoint(&self, other: &OrderedSet<T>) -> bool {
110        !self.iter().any(|value| other.contains(value))
111    }
112
113    /// Returns true if `other` contains all values in `self`.
114    #[inline]
115    pub fn is_subset(&self, other: &OrderedSet<T>) -> bool {
116        self.iter().all(|value| other.contains(value))
117    }
118
119    /// Returns true if `self` contains all values in `other`.
120    #[inline]
121    pub fn is_superset(&self, other: &OrderedSet<T>) -> bool {
122        other.is_subset(self)
123    }
124}
125
126impl<'a, T> IntoIterator for &'a OrderedSet<T> {
127    type Item = &'a T;
128    type IntoIter = Iter<'a, T>;
129
130    fn into_iter(self) -> Iter<'a, T> {
131        self.iter()
132    }
133}
134
135/// An iterator over the values in a `OrderedSet`.
136pub struct Iter<'a, T> {
137    iter: ordered_map::Keys<'a, T, ()>,
138}
139
140impl<'a, T> Clone for Iter<'a, T> {
141    #[inline]
142    fn clone(&self) -> Self {
143        Self {
144            iter: self.iter.clone(),
145        }
146    }
147}
148
149impl<'a, T> fmt::Debug for Iter<'a, T>
150where
151    T: fmt::Debug,
152{
153    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
154        f.debug_list().entries(self.clone()).finish()
155    }
156}
157
158impl<'a, T> Iterator for Iter<'a, T> {
159    type Item = &'a T;
160
161    #[inline]
162    fn next(&mut self) -> Option<&'a T> {
163        self.iter.next()
164    }
165
166    #[inline]
167    fn size_hint(&self) -> (usize, Option<usize>) {
168        self.iter.size_hint()
169    }
170}
171
172impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
173    #[inline]
174    fn next_back(&mut self) -> Option<&'a T> {
175        self.iter.next_back()
176    }
177}
178
179impl<'a, T> ExactSizeIterator for Iter<'a, T> {}
180
181impl<'a, T> FusedIterator for Iter<'a, T> {}