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: &T| 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: &T| 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> {}
182

Provided by KDAB

Privacy Policy
Learn Rust with the experts
Find out more