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> OrderedSet<T> {
33 /// Returns the number of elements in the `OrderedSet`.
34 #[inline]
35 pub const fn len(&self) -> usize {
36 self.map.len()
37 }
38
39 /// Returns true if the `OrderedSet` contains no elements.
40 #[inline]
41 pub const fn is_empty(&self) -> bool {
42 self.len() == 0
43 }
44
45 /// Returns a reference to the set's internal static instance of the given
46 /// key.
47 ///
48 /// This can be useful for interning schemes.
49 pub fn get_key<U: ?Sized>(&self, key: &U) -> Option<&T>
50 where
51 U: Eq + PhfHash,
52 T: PhfBorrow<U>,
53 {
54 self.map.get_key(key)
55 }
56
57 /// Returns the index of the key within the list used to initialize
58 /// the ordered set.
59 pub fn get_index<U: ?Sized>(&self, key: &U) -> Option<usize>
60 where
61 U: Eq + PhfHash,
62 T: PhfBorrow<U>,
63 {
64 self.map.get_index(key)
65 }
66
67 /// Returns a reference to the key at an index
68 /// within the list used to initialize the ordered set. See `.get_index(key)`.
69 pub fn index(&self, index: usize) -> Option<&T> {
70 self.map.index(index).map(|(k, &())| k)
71 }
72
73 /// Returns true if `value` is in the `OrderedSet`.
74 pub fn contains<U: ?Sized>(&self, value: &U) -> bool
75 where
76 U: Eq + PhfHash,
77 T: PhfBorrow<U>,
78 {
79 self.map.contains_key(value)
80 }
81
82 /// Returns an iterator over the values in the set.
83 ///
84 /// Values are returned in the same order in which they were defined.
85 pub fn iter(&self) -> Iter<'_, T> {
86 Iter {
87 iter: self.map.keys(),
88 }
89 }
90}
91
92impl<T> OrderedSet<T>
93where
94 T: Eq + PhfHash + PhfBorrow<T>,
95{
96 /// Returns true if `other` shares no elements with `self`.
97 #[inline]
98 pub fn is_disjoint(&self, other: &OrderedSet<T>) -> bool {
99 !self.iter().any(|value: &T| other.contains(value))
100 }
101
102 /// Returns true if `other` contains all values in `self`.
103 #[inline]
104 pub fn is_subset(&self, other: &OrderedSet<T>) -> bool {
105 self.iter().all(|value: &T| other.contains(value))
106 }
107
108 /// Returns true if `self` contains all values in `other`.
109 #[inline]
110 pub fn is_superset(&self, other: &OrderedSet<T>) -> bool {
111 other.is_subset(self)
112 }
113}
114
115impl<'a, T> IntoIterator for &'a OrderedSet<T> {
116 type Item = &'a T;
117 type IntoIter = Iter<'a, T>;
118
119 fn into_iter(self) -> Iter<'a, T> {
120 self.iter()
121 }
122}
123
124/// An iterator over the values in a `OrderedSet`.
125pub struct Iter<'a, T> {
126 iter: ordered_map::Keys<'a, T, ()>,
127}
128
129impl<'a, T> Clone for Iter<'a, T> {
130 #[inline]
131 fn clone(&self) -> Self {
132 Self {
133 iter: self.iter.clone(),
134 }
135 }
136}
137
138impl<'a, T> fmt::Debug for Iter<'a, T>
139where
140 T: fmt::Debug,
141{
142 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
143 f.debug_list().entries(self.clone()).finish()
144 }
145}
146
147impl<'a, T> Iterator for Iter<'a, T> {
148 type Item = &'a T;
149
150 #[inline]
151 fn next(&mut self) -> Option<&'a T> {
152 self.iter.next()
153 }
154
155 #[inline]
156 fn size_hint(&self) -> (usize, Option<usize>) {
157 self.iter.size_hint()
158 }
159}
160
161impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
162 #[inline]
163 fn next_back(&mut self) -> Option<&'a T> {
164 self.iter.next_back()
165 }
166}
167
168impl<'a, T> ExactSizeIterator for Iter<'a, T> {}
169
170impl<'a, T> FusedIterator for Iter<'a, T> {}
171