variant_set/lib.rs
1#![warn(clippy::all, clippy::pedantic)]
2use std::{
3 collections::HashMap,
4 hash::{BuildHasherDefault, Hash},
5};
6
7use nohash_hasher::NoHashHasher;
8pub use variant_set_derive::VariantEnum;
9
10/// A trait that must be implemented by enums that are used with `VariantSet`.
11///
12/// This trait provides a way to get the variant of an enum, which is another enum that represents the variants of the original enum,
13/// but without the data.
14pub trait VariantEnum {
15 /// The enum that represents the variants of the original enum, but without the data.
16 type Variant: Copy + Eq + Hash;
17
18 /// For a given value of the enum, returns the variant of the enum.
19 fn variant(&self) -> Self::Variant;
20}
21
22/// A set of values that are variants of an enum. The set can contain at most one value for each variant.
23/// Functionally equivalent to a `HashSet<T>`, but the enum variants can contain complex data.
24///
25/// The enum must implement the `VariantEnum` trait, you will generally want to derive it using the `VariantEnum` derive macro.
26///
27/// # Examples
28/// ```
29/// use variant_set::{VariantSet, VariantEnum};
30///
31/// #[derive(VariantEnum, Debug, PartialEq)]
32/// enum MyEnum {
33/// Variant1(String),
34/// Variant2(u32),
35/// Variant3(bool),
36/// }
37///
38/// let mut set = VariantSet::new();
39///
40/// set.set(MyEnum::Variant1("Hello".to_string()));
41/// set.set(MyEnum::Variant2(42));
42/// set.set(MyEnum::Variant3(true));
43///
44/// assert!(set.contains(MyEnumVariant::Variant1));
45/// assert!(set.contains(MyEnumVariant::Variant2));
46/// assert!(set.contains(MyEnumVariant::Variant3));
47///
48/// assert_eq!(set.get(MyEnumVariant::Variant1), Some(&MyEnum::Variant1("Hello".to_string())));
49/// assert_eq!(set.get(MyEnumVariant::Variant2), Some(&MyEnum::Variant2(42)));
50/// assert_eq!(set.get(MyEnumVariant::Variant3), Some(&MyEnum::Variant3(true)));
51/// ```
52///
53/// # Performance
54///
55/// The `VariantSet` is backed by a `HashMap` and provides constant time insertion, removal, and lookup.
56///
57pub struct VariantSet<T>
58where
59 T: VariantEnum,
60{
61 data: HashMap<T::Variant, T, BuildHasherDefault<NoHashHasher<usize>>>,
62}
63
64impl<T> VariantSet<T>
65where
66 T: VariantEnum,
67{
68 /// Creates a new `VariantSet` with a default capacity and hasher.
69 ///
70 /// # Examples
71 /// ```
72 /// use variant_set::{VariantSet, VariantEnum};
73 ///
74 /// #[derive(VariantEnum)]
75 /// enum MyEnum {
76 /// Variant1(String),
77 /// Variant2(u32),
78 /// }
79 ///
80 /// let set: VariantSet<MyEnum> = VariantSet::new();
81 /// ```
82 #[must_use]
83 pub fn new() -> Self {
84 Self {
85 data: HashMap::with_hasher(BuildHasherDefault::default()),
86 }
87 }
88
89 /// Creates a new `VariantSet` with a specified capacity.
90 ///
91 /// # Examples
92 /// ```
93 /// use variant_set::{VariantSet, VariantEnum};
94 ///
95 /// #[derive(VariantEnum)]
96 /// enum MyEnum {
97 /// Variant1(String),
98 /// Variant2(u32),
99 /// }
100 ///
101 /// let set: VariantSet<MyEnum> = VariantSet::with_capacity(10);
102 /// assert!(set.capacity() >= 10);
103 /// ```
104 #[must_use]
105 pub fn with_capacity(capacity: usize) -> Self {
106 Self {
107 data: HashMap::with_capacity_and_hasher(capacity, BuildHasherDefault::default()),
108 }
109 }
110
111 /// Returns the number of elements this set can hold without reallocating.
112 ///
113 /// # Examples
114 /// ```
115 /// use variant_set::{VariantSet, VariantEnum};
116 ///
117 /// #[derive(VariantEnum)]
118 /// enum MyEnum {
119 /// Variant1(String),
120 /// Variant2(u32),
121 /// }
122 ///
123 /// let set: VariantSet<MyEnum> = VariantSet::with_capacity(10);
124 /// assert!(set.capacity() >= 10);
125 /// ```
126 #[must_use]
127 pub fn capacity(&self) -> usize {
128 self.data.capacity()
129 }
130
131 /// Clears the set, removing all values.
132 ///
133 /// # Examples
134 /// ```
135 /// use variant_set::{VariantSet, VariantEnum};
136 ///
137 /// #[derive(VariantEnum)]
138 /// enum MyEnum {
139 /// Variant1(String),
140 /// Variant2(u32),
141 /// }
142 ///
143 /// let mut set = VariantSet::new();
144 /// set.set(MyEnum::Variant1("Hello".to_string()));
145 /// set.clear();
146 /// assert!(set.is_empty());
147 /// ```
148 pub fn clear(&mut self) {
149 self.data.clear();
150 }
151
152 /// Adds a value to the set.
153 ///
154 /// Returns whether the value was newly inserted. That is:
155 ///
156 /// * If the set did not previously contain this value, `true` is returned.
157 /// * If the set already contained this value, `false` is returned, and the set is not modified: original value is not replaced, and the value passed as argument is dropped.
158 ///
159 /// Note that if the set already contains a value, but the contained value is not equal to the value passed as argument, the value passed as argument is dropped and `false` is returned.
160 ///
161 /// # Examples
162 /// ```
163 /// use variant_set::{VariantSet, VariantEnum};
164 ///
165 /// #[derive(VariantEnum)]
166 /// enum MyEnum {
167 /// Variant1(String),
168 /// Variant2(u32),
169 /// }
170 ///
171 /// let mut set = VariantSet::new();
172 /// assert!(set.insert(MyEnum::Variant1("Hello".to_string())));
173 /// assert!(!set.insert(MyEnum::Variant1("World".to_string())));
174 /// ```
175 pub fn insert(&mut self, value: T) -> bool {
176 if let std::collections::hash_map::Entry::Vacant(entry) = self.data.entry(value.variant()) {
177 entry.insert(value);
178 true
179 } else {
180 false
181 }
182 }
183
184 /// Sets a value in the set. If a previous value existed, it is returned.
185 ///
186 /// # Examples
187 /// ```
188 /// use variant_set::{VariantSet, VariantEnum};
189 ///
190 /// #[derive(VariantEnum, PartialEq, Debug)]
191 /// enum MyEnum {
192 /// Variant1(String),
193 /// Variant2(u32),
194 /// }
195 ///
196 /// let mut set = VariantSet::new();
197 /// let previous = set.set(MyEnum::Variant1("Hello".to_string()));
198 /// assert_eq!(previous, None);
199 ///
200 /// let previous = set.set(MyEnum::Variant1("World".to_string()));
201 /// assert_eq!(previous, Some(MyEnum::Variant1("Hello".to_string())));
202 /// ```
203 pub fn set(&mut self, value: T) -> Option<T> {
204 self.data.insert(value.variant(), value)
205 }
206
207 /// Returns `true` if the set contains a value.
208 ///
209 /// # Examples
210 /// ```
211 /// use variant_set::{VariantSet, VariantEnum};
212 ///
213 /// #[derive(VariantEnum)]
214 /// enum MyEnum {
215 /// Variant1(String),
216 /// Variant2(u32),
217 /// }
218 ///
219 /// let mut set = VariantSet::new();
220 /// set.set(MyEnum::Variant1("Hello".to_string()));
221 /// assert!(set.contains(MyEnumVariant::Variant1));
222 /// ```
223 pub fn contains(&self, value: T::Variant) -> bool {
224 self.data.contains_key(&value)
225 }
226
227 /// Returns `true` if the set contains a value that is equal to the given value.
228 ///
229 /// # Examples
230 /// ```
231 /// use variant_set::{VariantSet, VariantEnum};
232 ///
233 /// #[derive(VariantEnum, Debug, PartialEq)]
234 /// enum MyEnum {
235 /// Variant1(String),
236 /// Variant2(u32),
237 /// }
238 ///
239 /// let mut set = VariantSet::new();
240 /// set.set(MyEnum::Variant1("Hello".to_string()));
241 /// assert!(set.contains_exact(&MyEnum::Variant1("Hello".to_string())));
242 /// assert!(!set.contains_exact(&MyEnum::Variant1("World".to_string())));
243 /// ```
244 pub fn contains_exact(&self, value: &T) -> bool
245 where
246 T: PartialEq,
247 {
248 matches!(self.data.get(&value.variant()), Some(v) if v == value)
249 }
250
251 /// Clears the set, returning all elements as an iterator. Keeps the allocated memory for reuse.
252 ///
253 /// # Examples
254 /// ```
255 /// use variant_set::{VariantSet, VariantEnum};
256 ///
257 /// #[derive(VariantEnum, Debug, PartialEq)]
258 /// enum MyEnum {
259 /// Variant1(String),
260 /// Variant2(u32),
261 /// }
262 ///
263 /// let mut set = VariantSet::new();
264 /// set.set(MyEnum::Variant1("Hello".to_string()));
265 /// set.set(MyEnum::Variant2(42));
266 /// let values: Vec<_> = set.drain().collect();
267 ///
268 /// assert_eq!(values.len(), 2);
269 /// assert!(values.contains(&MyEnum::Variant1("Hello".to_string())));
270 /// assert!(values.contains(&MyEnum::Variant2(42)));
271 /// ```
272 pub fn drain(&mut self) -> impl Iterator<Item = T> + '_ {
273 self.data.drain().map(|(_, value)| value)
274 }
275
276 /// Returns a reference to the value in the set, if any, that is equal to the given value.
277 ///
278 /// # Examples
279 /// ```
280 /// use variant_set::{VariantSet, VariantEnum};
281 ///
282 /// #[derive(VariantEnum, Debug, PartialEq)]
283 /// enum MyEnum {
284 /// Variant1(String),
285 /// Variant2(u32),
286 /// }
287 ///
288 /// let mut set = VariantSet::new();
289 /// set.set(MyEnum::Variant1("Hello".to_string()));
290 /// let value = set.get(MyEnumVariant::Variant1);
291 /// assert_eq!(value, Some(&MyEnum::Variant1("Hello".to_string())));
292 /// ```
293 pub fn get(&self, value: T::Variant) -> Option<&T> {
294 self.data.get(&value)
295 }
296
297 /// Inserts the given `value` into the set if it is not present, then returns a reference to the value in the set.
298 ///
299 /// # Examples
300 /// ```
301 /// use variant_set::{VariantSet, VariantEnum};
302 ///
303 /// #[derive(VariantEnum, Debug, PartialEq)]
304 /// enum MyEnum {
305 /// Variant1(String),
306 /// Variant2(u32),
307 /// }
308 ///
309 /// let mut set = VariantSet::new();
310 /// let value = set.get_or_insert(MyEnum::Variant1("Hello".to_string()));
311 /// assert_eq!(value, &MyEnum::Variant1("Hello".to_string()));
312 /// ```
313 pub fn get_or_insert(&mut self, default: T) -> &T {
314 self.data.entry(default.variant()).or_insert(default)
315 }
316
317 /// Returns `true` if the set contains no elements.
318 ///
319 /// # Examples
320 /// ```
321 /// use variant_set::{VariantSet, VariantEnum};
322 ///
323 /// #[derive(VariantEnum)]
324 /// enum MyEnum {
325 /// Variant1(String),
326 /// Variant2(u32),
327 /// }
328 ///
329 /// let set: VariantSet<MyEnum> = VariantSet::new();
330 /// assert!(set.is_empty());
331 /// ```
332 #[must_use]
333 pub fn is_empty(&self) -> bool {
334 self.data.is_empty()
335 }
336
337 /// An iterator visiting all elements in arbitrary order. The iterator element type is `&'a T`.
338 ///
339 /// # Examples
340 /// ```
341 /// use variant_set::{VariantSet, VariantEnum};
342 ///
343 /// #[derive(VariantEnum, Debug)]
344 /// enum MyEnum {
345 /// Variant1(String),
346 /// Variant2(u32),
347 /// }
348 ///
349 /// let mut set = VariantSet::new();
350 /// set.set(MyEnum::Variant1("Hello".to_string()));
351 /// set.set(MyEnum::Variant2(42));
352 ///
353 /// for value in set.iter() {
354 /// println!("{:?}", value);
355 /// }
356 /// ```
357 pub fn iter(&self) -> impl Iterator<Item = &T> {
358 self.data.values()
359 }
360
361 /// Returns the number of elements in the set.
362 ///
363 /// # Examples
364 /// ```
365 /// use variant_set::{VariantSet, VariantEnum};
366 ///
367 /// #[derive(VariantEnum)]
368 /// enum MyEnum {
369 /// Variant1(String),
370 /// Variant2(u32),
371 /// }
372 ///
373 /// let mut set = VariantSet::new();
374 /// set.set(MyEnum::Variant1("Hello".to_string()));
375 /// set.set(MyEnum::Variant2(42));
376 ///
377 /// assert_eq!(set.len(), 2);
378 /// ```
379 #[must_use]
380 pub fn len(&self) -> usize {
381 self.data.len()
382 }
383
384 /// Removes a variant from the set. Returns the value if it existed.
385 ///
386 /// # Examples
387 /// ```
388 /// use variant_set::{VariantSet, VariantEnum};
389 ///
390 /// #[derive(VariantEnum, Debug, PartialEq)]
391 /// enum MyEnum {
392 /// Variant1(String),
393 /// Variant2(u32),
394 /// }
395 ///
396 /// let mut set = VariantSet::new();
397 /// set.set(MyEnum::Variant1("Hello".to_string()));
398 /// let value = set.remove(MyEnumVariant::Variant1);
399 /// assert_eq!(value, Some(MyEnum::Variant1("Hello".to_string())));
400 /// ```
401 pub fn remove(&mut self, value: T::Variant) -> Option<T> {
402 self.data.remove(&value)
403 }
404
405 /// Removes a variant from the set if it is equal to the given value. Returns the value if it existed.
406 ///
407 /// # Examples
408 /// ```
409 /// use variant_set::{VariantSet, VariantEnum};
410 ///
411 /// #[derive(VariantEnum, Debug, PartialEq)]
412 /// enum MyEnum {
413 /// Variant1(String),
414 /// Variant2(u32),
415 /// }
416 ///
417 /// let mut set = VariantSet::new();
418 /// set.set(MyEnum::Variant1("Hello".to_string()));
419 ///
420 /// let not_matching = set.remove_exact(&MyEnum::Variant1("World".to_string()));
421 /// assert_eq!(not_matching, None);
422 ///
423 /// let matching = set.remove_exact(&MyEnum::Variant1("Hello".to_string()));
424 /// assert_eq!(matching, Some(MyEnum::Variant1("Hello".to_string())));
425 /// ```
426 pub fn remove_exact(&mut self, value: &T) -> Option<T>
427 where
428 T: PartialEq,
429 {
430 match self.data.get(&value.variant()) {
431 Some(v) if v == value => self.data.remove(&value.variant()),
432 _ => None,
433 }
434 }
435
436 /// Reserves capacity for at least `additional` more elements to be inserted in the set.
437 /// The collection may reserve more space to avoid frequent reallocations.
438 /// After calling `reserve`, capacity will be greater than or equal to `self.len() + additional`.
439 /// Does nothing if the capacity is already sufficient.
440 ///
441 /// Note that you can reserve more capacity than there are variants in the enum.
442 ///
443 /// # Examples
444 /// ```
445 /// use variant_set::{VariantSet, VariantEnum};
446 ///
447 /// #[derive(VariantEnum)]
448 /// enum MyEnum {
449 /// Variant1(String),
450 /// Variant2(u32),
451 /// }
452 ///
453 /// let mut set: VariantSet<MyEnum> = VariantSet::new();
454 /// set.reserve(10);
455 /// assert!(set.capacity() >= 10);
456 /// ```
457 pub fn reserve(&mut self, additional: usize) {
458 self.data.reserve(additional);
459 }
460
461 /// Tries to reserve capacity for at least `additional` more elements to be inserted in the set.
462 /// The collection may reserve more space to avoid frequent reallocations.
463 /// After calling `try_reserve`, capacity will be greater than or equal to `self.len() + additional` if it returns Ok(())
464 /// Does nothing if the capacity is already sufficient.
465 ///
466 /// Note that you can reserve more capacity than there are variants in the enum.
467 ///
468 /// # Examples
469 /// ```
470 /// use variant_set::{VariantSet, VariantEnum};
471 ///
472 /// #[derive(VariantEnum)]
473 /// enum MyEnum {
474 /// Variant1(String),
475 /// Variant2(u32),
476 /// }
477 ///
478 /// let mut set: VariantSet<MyEnum> = VariantSet::new();
479 /// set.try_reserve(10).unwrap();
480 /// assert!(set.capacity() >= 10);
481 /// ```
482 ///
483 /// # Errors
484 ///
485 /// Returns a `std::collections::TryReserveError` if the new capacity would overflow usize.
486 pub fn try_reserve(
487 &mut self,
488 additional: usize,
489 ) -> Result<(), std::collections::TryReserveError> {
490 self.data.try_reserve(additional)
491 }
492
493 /// Shrinks the capacity of the set with a lower limit. It will drop down to no lower than the supplied limit while maintaining the internal
494 /// rules and possibly leaving some space in accordance with the resize policy.
495 ///
496 /// If the current capacity is less than the lower limit, this is a no-op.
497 ///
498 /// # Examples
499 /// ```
500 /// use variant_set::{VariantSet, VariantEnum};
501 ///
502 /// #[derive(VariantEnum)]
503 /// enum MyEnum {
504 /// Variant1(String),
505 /// Variant2(u32),
506 /// }
507 ///
508 /// let mut set: VariantSet<MyEnum> = VariantSet::new();
509 /// set.reserve(10);
510 /// set.shrink_to(5);
511 /// assert!(set.capacity() >= 5);
512 /// ```
513 pub fn shrink_to(&mut self, min_capacity: usize) {
514 self.data.shrink_to(min_capacity);
515 }
516
517 /// Shrinks the capacity of the set as much as possible.
518 /// It will drop down as much as possible while maintaining the internal rules and possibly leaving some space in accordance with the resize policy.
519 ///
520 /// # Examples
521 /// ```
522 /// use variant_set::{VariantSet, VariantEnum};
523 ///
524 /// #[derive(VariantEnum)]
525 /// enum MyEnum {
526 /// Variant1(String),
527 /// Variant2(u32),
528 /// }
529 ///
530 /// let mut set: VariantSet<MyEnum> = VariantSet::new();
531 /// set.reserve(10);
532 /// set.set(MyEnum::Variant1("Hello".to_string()));
533 /// set.shrink_to_fit();
534 /// assert!(set.capacity() >= 1);
535 /// ```
536 pub fn shrink_to_fit(&mut self) {
537 self.data.shrink_to_fit();
538 }
539
540 /// Removes and returns the value in the set, if any, that is equal to the given value.
541 ///
542 /// # Examples
543 /// ```
544 /// use variant_set::{VariantSet, VariantEnum};
545 ///
546 /// #[derive(VariantEnum, Debug, PartialEq)]
547 /// enum MyEnum {
548 /// Variant1(String),
549 /// Variant2(u32),
550 /// }
551 ///
552 /// let mut set = VariantSet::new();
553 /// set.set(MyEnum::Variant1("Hello".to_string()));
554 /// let value = set.take(MyEnumVariant::Variant1);
555 /// assert_eq!(value, Some(MyEnum::Variant1("Hello".to_string())));
556 /// ```
557 pub fn take(&mut self, value: T::Variant) -> Option<T> {
558 self.data.remove(&value)
559 }
560}
561
562impl<T> Default for VariantSet<T>
563where
564 T: VariantEnum,
565{
566 /// Creates a new `VariantSet` with a default capacity.
567 /// The default capacity is the capacity of a newly created `HashMap`.
568 ///
569 /// # Examples
570 /// ```
571 /// use variant_set::{VariantSet, VariantEnum};
572 ///
573 /// #[derive(VariantEnum)]
574 /// enum MyEnum {
575 /// Variant1(String),
576 /// Variant2(u32),
577 /// }
578 ///
579 /// let set: VariantSet<MyEnum> = Default::default();
580 /// ```
581 fn default() -> Self {
582 Self::new()
583 }
584}
585
586impl<T> Clone for VariantSet<T>
587where
588 T: VariantEnum + Clone,
589{
590 /// Clones the set. The values are cloned using their `Clone` implementation.
591 ///
592 /// # Examples
593 /// ```
594 /// use variant_set::{VariantSet, VariantEnum};
595 ///
596 /// #[derive(VariantEnum, Debug, Clone, PartialEq)]
597 /// enum MyEnum {
598 /// Variant1(String),
599 /// Variant2(u32),
600 /// }
601 ///
602 /// let mut set = VariantSet::new();
603 /// set.set(MyEnum::Variant1("Hello".to_string()));
604 /// set.set(MyEnum::Variant2(42));
605 ///
606 /// let cloned = set.clone();
607 /// assert_eq!(set, cloned);
608 /// ```
609 fn clone(&self) -> Self {
610 Self {
611 data: self.data.clone(),
612 }
613 }
614}
615
616impl<T> std::fmt::Debug for VariantSet<T>
617where
618 T: VariantEnum + std::fmt::Debug,
619 T::Variant: std::fmt::Debug,
620{
621 /// Formats the set as a map of variants to values.
622 /// The values are formatted using their `Debug` implementation.
623 /// The variants are formatted using their `Debug` implementation.
624 ///
625 /// # Examples
626 /// ```
627 /// use variant_set::{VariantSet, VariantEnum};
628 ///
629 /// #[derive(VariantEnum, Debug)]
630 /// enum MyEnum {
631 /// Variant1(String),
632 /// Variant2(u32),
633 /// }
634 ///
635 /// let mut set = VariantSet::new();
636 /// set.set(MyEnum::Variant1("Hello".to_string()));
637 /// set.set(MyEnum::Variant2(42));
638 ///
639 /// println!("{:?}", set);
640 /// ```
641 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
642 f.debug_map().finish()
643 }
644}
645
646impl<T> PartialEq for VariantSet<T>
647where
648 T: VariantEnum + PartialEq,
649{
650 /// Compares two sets for equality.
651 /// Two sets are equal if they contain the same variants, regardless of the order.
652 /// The values of the variants must be equal for the sets to be equal.
653 ///
654 /// # Examples
655 /// ```
656 /// use variant_set::{VariantSet, VariantEnum};
657 ///
658 /// #[derive(VariantEnum, Debug, PartialEq)]
659 /// enum MyEnum {
660 /// Variant1(String),
661 /// Variant2(u32),
662 /// }
663 ///
664 /// let mut set1 = VariantSet::new();
665 /// set1.set(MyEnum::Variant1("Hello".to_string()));
666 /// set1.set(MyEnum::Variant2(42));
667 ///
668 /// let mut set2 = VariantSet::new();
669 /// set2.set(MyEnum::Variant2(42));
670 /// set2.set(MyEnum::Variant1("Hello".to_string()));
671 ///
672 /// assert_eq!(set1, set2);
673 /// ```
674 fn eq(&self, other: &Self) -> bool {
675 self.data == other.data
676 }
677}
678
679impl<T> Eq for VariantSet<T> where T: VariantEnum + Eq {}
680
681impl<T> Extend<T> for VariantSet<T>
682where
683 T: VariantEnum,
684{
685 /// Extends the set with the contents of an iterator.
686 /// If the set already contains a value that maps to the same variant, the value will be replaced.
687 /// If the iterator yields multiple values that map to the same variant, the last value will be used.
688 ///
689 /// # Examples
690 /// ```
691 /// use variant_set::{VariantSet, VariantEnum};
692 ///
693 /// #[derive(VariantEnum, Debug, PartialEq)]
694 /// enum MyEnum {
695 /// Variant1(String),
696 /// Variant2(u32),
697 /// }
698 ///
699 /// let mut set = VariantSet::new();
700 /// set.set(MyEnum::Variant2(10));
701 /// set.extend(vec![MyEnum::Variant1("Hello".to_string()), MyEnum::Variant2(42), MyEnum::Variant1("World".to_string())]);
702 ///
703 /// assert_eq!(set.len(), 2);
704 /// assert!(set.contains_exact(&MyEnum::Variant1("World".to_string())));
705 /// assert!(set.contains_exact(&MyEnum::Variant2(42)));
706 /// ```
707 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
708 for value in iter {
709 self.set(value);
710 }
711 }
712}
713
714impl<T> IntoIterator for VariantSet<T>
715where
716 T: VariantEnum,
717{
718 type Item = T;
719 type IntoIter = std::collections::hash_map::IntoValues<T::Variant, T>;
720
721 /// Consumes the set and returns an iterator over the values.
722 ///
723 /// # Examples
724 /// ```
725 /// use variant_set::{VariantSet, VariantEnum};
726 ///
727 /// #[derive(VariantEnum, Debug, PartialEq)]
728 /// enum MyEnum {
729 /// Variant1(String),
730 /// Variant2(u32),
731 /// }
732 ///
733 /// let mut set = VariantSet::new();
734 /// set.set(MyEnum::Variant1("Hello".to_string()));
735 /// set.set(MyEnum::Variant2(42));
736 ///
737 /// let values: Vec<_> = set.into_iter().collect();
738 ///
739 /// assert_eq!(values.len(), 2);
740 /// assert!(values.contains(&MyEnum::Variant1("Hello".to_string())));
741 /// assert!(values.contains(&MyEnum::Variant2(42)));
742 /// ```
743 fn into_iter(self) -> Self::IntoIter {
744 self.data.into_values()
745 }
746}
747
748impl<T> FromIterator<T> for VariantSet<T>
749where
750 T: VariantEnum,
751{
752 /// Creates a new `VariantSet` from an iterator.
753 /// If the iterator yields multiple values that map to the same variant, the last value will be used.
754 ///
755 /// # Examples
756 /// ```
757 /// use variant_set::{VariantSet, VariantEnum};
758 ///
759 /// #[derive(VariantEnum, Debug, PartialEq)]
760 /// enum MyEnum {
761 /// Variant1(String),
762 /// Variant2(u32),
763 /// }
764 ///
765 /// let iter = vec![MyEnum::Variant1("Hello".to_string()), MyEnum::Variant2(42), MyEnum::Variant1("World".to_string())].into_iter();
766 /// let set = VariantSet::from_iter(iter);
767 ///
768 /// assert_eq!(set.len(), 2);
769 /// assert!(set.contains_exact(&MyEnum::Variant1("World".to_string())));
770 /// ```
771 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
772 let mut set = VariantSet::new();
773 set.extend(iter);
774 set
775 }
776}
777
778impl<T, const N: usize> From<[T; N]> for VariantSet<T>
779where
780 T: VariantEnum,
781{
782 /// Creates a new `VariantSet` from an array.
783 ///
784 /// # Examples
785 /// ```
786 /// use variant_set::{VariantSet, VariantEnum};
787 ///
788 /// #[derive(VariantEnum)]
789 /// enum MyEnum {
790 /// Variant1(String),
791 /// Variant2(u32),
792 /// }
793 ///
794 /// let array = [MyEnum::Variant1("Hello".to_string()), MyEnum::Variant2(42)];
795 /// let set = VariantSet::from(array);
796 ///
797 /// assert_eq!(set.len(), 2);
798 /// ```
799 fn from(array: [T; N]) -> Self {
800 Self::from_iter(array)
801 }
802}