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> 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| 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| 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> {}