wasmtime_environ/collections/
index_set.rs1use crate::{
2 collections::{TryClone, TryFromIterator},
3 error::OutOfMemory,
4};
5use core::{
6 borrow::Borrow,
7 fmt,
8 hash::{BuildHasher, Hash},
9 marker::PhantomData,
10 mem,
11 ops::Index,
12};
13use indexmap::set as inner;
14
15#[cfg(feature = "std")]
16use std::hash::RandomState as DefaultHashBuilder;
17
18#[cfg(not(feature = "std"))]
19use hashbrown::DefaultHashBuilder;
20
21pub struct TryIndexSet<T, S = DefaultHashBuilder> {
24 inner: indexmap::IndexSet<T, S>,
25}
26
27impl<T, S> Default for TryIndexSet<T, S>
28where
29 S: Default,
30{
31 fn default() -> Self {
32 Self {
33 inner: indexmap::IndexSet::default(),
34 }
35 }
36}
37
38impl<T, S> PartialEq for TryIndexSet<T, S>
39where
40 T: Eq + Hash,
41 S: BuildHasher,
42{
43 fn eq(&self, other: &Self) -> bool {
44 self.inner.eq(&other.inner)
45 }
46}
47
48impl<T, S> Eq for TryIndexSet<T, S>
49where
50 T: Eq + Hash,
51 S: BuildHasher,
52{
53}
54
55impl<T, S> TryClone for TryIndexSet<T, S>
56where
57 T: Eq + Hash + TryClone,
58 S: BuildHasher + TryClone,
59{
60 fn try_clone(&self) -> Result<Self, OutOfMemory> {
61 let mut set = Self::with_hasher(self.inner.hasher().try_clone()?);
62 set.reserve(self.len())?;
63 for value in self.iter() {
64 set.insert(value.try_clone()?)?;
65 }
66 Ok(set)
67 }
68}
69
70impl<T, S> fmt::Debug for TryIndexSet<T, S>
71where
72 T: fmt::Debug,
73{
74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75 fmt::Debug::fmt(&self.inner, f)
76 }
77}
78
79impl<T, S> From<TryIndexSet<T, S>> for indexmap::IndexSet<T, S> {
80 fn from(set: TryIndexSet<T, S>) -> Self {
81 set.inner
82 }
83}
84
85impl<T, S> From<indexmap::IndexSet<T, S>> for TryIndexSet<T, S> {
86 fn from(inner: indexmap::IndexSet<T, S>) -> Self {
87 Self { inner }
88 }
89}
90
91impl<T, S> serde::ser::Serialize for TryIndexSet<T, S>
92where
93 T: serde::ser::Serialize,
94{
95 fn serialize<Ser>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error>
96 where
97 Ser: serde::Serializer,
98 {
99 use serde::ser::SerializeSeq as _;
100 let mut seq = serializer.serialize_seq(Some(self.len()))?;
101 for value in self {
102 seq.serialize_element(value)?;
103 }
104 seq.end()
105 }
106}
107
108impl<'de, T> serde::de::Deserialize<'de> for TryIndexSet<T>
109where
110 T: serde::de::Deserialize<'de> + Hash + Eq,
111{
112 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
113 where
114 D: serde::Deserializer<'de>,
115 {
116 struct Visitor<T>(PhantomData<fn() -> TryIndexSet<T>>);
117
118 impl<'de, T> serde::de::Visitor<'de> for Visitor<T>
119 where
120 T: serde::de::Deserialize<'de> + Hash + Eq,
121 {
122 type Value = TryIndexSet<T>;
123
124 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
125 f.write_str("an `IndexSet`")
126 }
127
128 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
129 where
130 A: serde::de::SeqAccess<'de>,
131 {
132 use serde::de::Error as _;
133
134 let mut result = TryIndexSet::<T>::new();
135
136 if let Some(len) = seq.size_hint() {
137 result.reserve(len).map_err(|oom| A::Error::custom(oom))?;
138 }
139
140 while let Some(value) = seq.next_element::<T>()? {
141 result.insert(value).map_err(|oom| A::Error::custom(oom))?;
142 }
143
144 Ok(result)
145 }
146 }
147
148 deserializer.deserialize_seq(Visitor(PhantomData))
149 }
150}
151
152impl<T> TryFromIterator<T, OutOfMemory> for TryIndexSet<T>
153where
154 T: Hash + Eq,
155{
156 fn try_from_iter<I>(iter: I) -> Result<Self, OutOfMemory>
157 where
158 I: Iterator<Item = T>,
159 {
160 let mut set = Self::new();
161 set.reserve(iter.size_hint().0)?;
162 for value in iter {
163 set.insert(value)?;
164 }
165 Ok(set)
166 }
167}
168
169impl<T, E> TryFromIterator<Result<T, E>, E> for TryIndexSet<T>
170where
171 T: Hash + Eq,
172 E: From<OutOfMemory>,
173{
174 fn try_from_iter<I>(iter: I) -> Result<Self, E>
175 where
176 I: Iterator<Item = Result<T, E>>,
177 {
178 let mut set = Self::new();
179 set.reserve(iter.size_hint().0)?;
180 for value in iter {
181 set.insert(value?)?;
182 }
183 Ok(set)
184 }
185}
186
187impl<T> TryIndexSet<T> {
188 pub fn new() -> Self {
190 Self {
191 inner: indexmap::IndexSet::with_hasher(Default::default()),
192 }
193 }
194}
195
196impl<T, S> TryIndexSet<T, S> {
197 pub const fn with_hasher(hash_builder: S) -> Self {
199 TryIndexSet {
200 inner: indexmap::IndexSet::with_hasher(hash_builder),
201 }
202 }
203
204 pub fn len(&self) -> usize {
206 self.inner.len()
207 }
208
209 pub fn is_empty(&self) -> bool {
211 self.inner.is_empty()
212 }
213
214 pub fn iter(&self) -> inner::Iter<'_, T> {
216 self.inner.iter()
217 }
218
219 pub fn get_index(&self, index: usize) -> Option<&T> {
221 self.inner.get_index(index)
222 }
223
224 pub fn reserve(&mut self, additional: usize) -> Result<(), OutOfMemory> {
227 self.inner.try_reserve(additional).map_err(|_| {
228 let new_len = self.len().saturating_add(additional);
229 OutOfMemory::new(new_len.saturating_mul(mem::size_of::<T>()))
230 })
231 }
232}
233
234impl<T, S> TryIndexSet<T, S>
235where
236 T: Hash + Eq,
237 S: BuildHasher,
238{
239 pub fn insert(&mut self, value: T) -> Result<bool, OutOfMemory> {
242 self.reserve(1)?;
243 Ok(self.inner.insert(value))
244 }
245
246 pub fn contains<Q>(&self, value: &Q) -> bool
248 where
249 Q: ?Sized + Hash + Eq,
250 T: Borrow<Q>,
251 {
252 self.inner.contains(value)
253 }
254
255 pub fn get_index_of<Q>(&self, value: &Q) -> Option<usize>
257 where
258 Q: ?Sized + Hash + Eq,
259 T: Borrow<Q>,
260 {
261 self.inner.get_index_of(value)
262 }
263}
264
265impl<T, S> Index<usize> for TryIndexSet<T, S> {
266 type Output = T;
267
268 fn index(&self, index: usize) -> &T {
269 &self.inner[index]
270 }
271}
272
273impl<'a, T, S> IntoIterator for &'a TryIndexSet<T, S> {
274 type Item = &'a T;
275 type IntoIter = inner::Iter<'a, T>;
276
277 fn into_iter(self) -> Self::IntoIter {
278 self.iter()
279 }
280}
281
282impl<T, S> IntoIterator for TryIndexSet<T, S> {
283 type Item = T;
284 type IntoIter = inner::IntoIter<T>;
285
286 fn into_iter(self) -> Self::IntoIter {
287 self.inner.into_iter()
288 }
289}