frozen_collections_core/fz_sets/
fz_string_set.rs1use crate::DefaultHashBuilder;
2use crate::fz_maps::FzStringMap;
3use crate::hashers::{LeftRangeHasher, RightRangeHasher};
4use crate::sets::decl_macros::{
5 bitand_fn, bitor_fn, bitxor_fn, debug_fn, into_iter_fn, into_iter_ref_fn, partial_eq_fn,
6 set_iteration_funcs, sub_fn,
7};
8use crate::sets::{IntoIter, Iter};
9use crate::traits::{Hasher, Len, MapIteration, MapQuery, Set, SetIteration, SetOps, SetQuery};
10use alloc::vec::Vec;
11use core::fmt::Debug;
12use core::hash::BuildHasher;
13use core::hash::Hash;
14use core::iter::FromIterator;
15use core::ops::{BitAnd, BitOr, BitXor, Sub};
16use equivalent::Equivalent;
17use foldhash::fast::RandomState;
18#[cfg(feature = "serde")]
19use {
20 crate::sets::decl_macros::serialize_fn,
21 core::fmt::Formatter,
22 core::marker::PhantomData,
23 serde::de::{SeqAccess, Visitor},
24 serde::ser::SerializeSeq,
25 serde::{Deserialize, Deserializer, Serialize, Serializer},
26};
27
28#[doc = include_str!("../doc_snippets/about.md")]
31#[doc = include_str!("../doc_snippets/hash_warning.md")]
32#[derive(Clone)]
38pub struct FzStringSet<T, BH = DefaultHashBuilder> {
39 map: FzStringMap<T, (), BH>,
40}
41
42impl<'a> FzStringSet<&'a str, DefaultHashBuilder> {
43 #[must_use]
45 pub fn new(entries: Vec<&'a str>) -> Self {
46 Self::with_hasher(entries, RandomState::default())
47 }
48}
49
50impl<'a, BH> FzStringSet<&'a str, BH>
51where
52 BH: BuildHasher,
53{
54 #[must_use]
56 pub fn with_hasher(entries: Vec<&'a str>, bh: BH) -> Self {
57 Self {
58 map: FzStringMap::with_hasher(entries.into_iter().map(|x| (x, ())).collect(), bh),
59 }
60 }
61}
62
63impl<BH> Default for FzStringSet<&str, BH>
64where
65 BH: Default,
66{
67 fn default() -> Self {
68 Self {
69 map: FzStringMap::default(),
70 }
71 }
72}
73
74impl<'a, BH> From<FzStringMap<&'a str, (), BH>> for FzStringSet<&'a str, BH> {
75 fn from(map: FzStringMap<&'a str, (), BH>) -> Self {
76 Self { map }
77 }
78}
79
80impl<'a, const N: usize, BH> From<[&'a str; N]> for FzStringSet<&'a str, BH>
81where
82 BH: BuildHasher + Default,
83{
84 fn from(entries: [&'a str; N]) -> Self {
85 Self::from(FzStringMap::from_iter(entries.into_iter().map(|x| (x, ()))))
86 }
87}
88
89impl<'a, BH> FromIterator<&'a str> for FzStringSet<&'a str, BH>
90where
91 BH: BuildHasher + Default,
92{
93 fn from_iter<IT: IntoIterator<Item = &'a str>>(iter: IT) -> Self {
94 Self::from(FzStringMap::from_iter(iter.into_iter().map(|x| (x, ()))))
95 }
96}
97
98impl<T, Q, BH> Set<T, Q> for FzStringSet<T, BH>
99where
100 Q: ?Sized + Hash + Eq + Len + Equivalent<T>,
101 BH: BuildHasher,
102 LeftRangeHasher<BH>: Hasher<Q>,
103 RightRangeHasher<BH>: Hasher<Q>,
104{
105}
106
107impl<T, Q, BH> SetQuery<T, Q> for FzStringSet<T, BH>
108where
109 Q: ?Sized + Hash + Eq + Len + Equivalent<T>,
110 BH: BuildHasher,
111 LeftRangeHasher<BH>: Hasher<Q>,
112 RightRangeHasher<BH>: Hasher<Q>,
113{
114 #[inline]
115 fn get(&self, value: &Q) -> Option<&T> {
116 Some(self.map.get_key_value(value)?.0)
117 }
118}
119
120impl<T, BH> SetIteration<T> for FzStringSet<T, BH> {
121 type Iterator<'a>
122 = Iter<'a, T>
123 where
124 T: 'a,
125 BH: 'a;
126
127 set_iteration_funcs!();
128}
129
130impl<T, BH> Len for FzStringSet<T, BH> {
131 fn len(&self) -> usize {
132 self.map.len()
133 }
134}
135
136impl<T, ST, BH> BitOr<&ST> for &FzStringSet<T, BH>
137where
138 T: Hash + Eq + Len + Clone,
139 ST: Set<T>,
140 BH: BuildHasher + Default,
141 LeftRangeHasher<BH>: Hasher<T>,
142 RightRangeHasher<BH>: Hasher<T>,
143{
144 bitor_fn!();
145}
146
147impl<T, ST, BH> BitAnd<&ST> for &FzStringSet<T, BH>
148where
149 T: Hash + Eq + Len + Clone,
150 ST: Set<T>,
151 BH: BuildHasher + Default,
152 LeftRangeHasher<BH>: Hasher<T>,
153 RightRangeHasher<BH>: Hasher<T>,
154{
155 bitand_fn!();
156}
157
158impl<T, ST, BH> BitXor<&ST> for &FzStringSet<T, BH>
159where
160 T: Hash + Eq + Len + Clone,
161 ST: Set<T>,
162 BH: BuildHasher + Default,
163 LeftRangeHasher<BH>: Hasher<T>,
164 RightRangeHasher<BH>: Hasher<T>,
165{
166 bitxor_fn!();
167}
168
169impl<T, ST, BH> Sub<&ST> for &FzStringSet<T, BH>
170where
171 T: Hash + Eq + Len + Clone,
172 ST: Set<T>,
173 BH: BuildHasher + Default,
174 LeftRangeHasher<BH>: Hasher<T>,
175 RightRangeHasher<BH>: Hasher<T>,
176{
177 sub_fn!();
178}
179
180impl<T, BH> IntoIterator for FzStringSet<T, BH> {
181 into_iter_fn!();
182}
183
184impl<'a, T, BH> IntoIterator for &'a FzStringSet<T, BH> {
185 into_iter_ref_fn!();
186}
187
188impl<T, ST, BH> PartialEq<ST> for FzStringSet<T, BH>
189where
190 T: Hash + Eq + Len,
191 ST: Set<T>,
192 BH: BuildHasher + Default,
193 LeftRangeHasher<BH>: Hasher<T>,
194 RightRangeHasher<BH>: Hasher<T>,
195{
196 partial_eq_fn!();
197}
198
199impl<T, BH> Eq for FzStringSet<T, BH>
200where
201 T: Hash + Eq + Len,
202 BH: BuildHasher + Default,
203 LeftRangeHasher<BH>: Hasher<T>,
204 RightRangeHasher<BH>: Hasher<T>,
205{
206}
207
208impl<T, BH> Debug for FzStringSet<T, BH>
209where
210 T: Debug,
211{
212 debug_fn!();
213}
214
215#[cfg(feature = "serde")]
216impl<T> Serialize for FzStringSet<T>
217where
218 T: Serialize,
219{
220 serialize_fn!();
221}
222
223#[cfg(feature = "serde")]
224impl<'de, BH> Deserialize<'de> for FzStringSet<&'de str, BH>
225where
226 BH: BuildHasher + Default,
227{
228 fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
229 where
230 D: Deserializer<'de>,
231 {
232 deserializer.deserialize_seq(SetVisitor {
233 marker: PhantomData,
234 })
235 }
236}
237
238#[cfg(feature = "serde")]
239struct SetVisitor<BH> {
240 marker: PhantomData<BH>,
241}
242
243#[cfg(feature = "serde")]
244impl<'de, BH> Visitor<'de> for SetVisitor<BH>
245where
246 BH: BuildHasher + Default,
247{
248 type Value = FzStringSet<&'de str, BH>;
249
250 fn expecting(&self, formatter: &mut Formatter) -> core::fmt::Result {
251 formatter.write_str("a set with string values")
252 }
253
254 fn visit_seq<M>(self, mut access: M) -> core::result::Result<Self::Value, M::Error>
255 where
256 M: SeqAccess<'de>,
257 {
258 let mut v = Vec::with_capacity(access.size_hint().unwrap_or(0));
259 while let Some(x) = access.next_element()? {
260 v.push((x, ()));
261 }
262
263 Ok(FzStringSet::from(FzStringMap::with_hasher(
264 v,
265 BH::default(),
266 )))
267 }
268}