1use crate::repr::EnumSetTypeRepr;
2use crate::traits::EnumSetType;
3use crate::EnumSetTypeWithRepr;
4use core::cmp::Ordering;
5use core::fmt::{Debug, Display, Formatter};
6use core::hash::{Hash, Hasher};
7use core::iter::Sum;
8use core::ops::{
9 BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Sub, SubAssign,
10};
11
12#[cfg(feature = "serde")]
13use {
14 serde2 as serde,
15 serde2::{Deserialize, Serialize},
16};
17
18#[cfg_attr(
118 not(feature = "serde"),
119 doc = "\n\n",
120 doc = "[`Serialize`]: https://docs.rs/serde/latest/serde/trait.Serialize.html\n",
121 doc = "[`Deserialize`]: https://docs.rs/serde/latest/serde/trait.Deserialize.html\n"
122)]
123#[derive(Copy, Clone, PartialEq, Eq)]
124#[repr(transparent)]
125pub struct EnumSet<T: EnumSetType> {
126 #[doc(hidden)]
127 pub __priv_repr: T::Repr,
130}
131
132impl<T: EnumSetType> EnumSet<T> {
134 const EMPTY_REPR: Self = EnumSet { __priv_repr: T::Repr::EMPTY };
135 const ALL_REPR: Self = EnumSet { __priv_repr: T::ALL_BITS };
136
137 #[inline(always)]
139 pub const fn new() -> Self {
140 Self::EMPTY_REPR
141 }
142
143 #[inline(always)]
145 pub fn only(t: T) -> Self {
146 let mut set = Self::new();
147 set.insert(t);
148 set
149 }
150
151 #[inline(always)]
155 pub const fn empty() -> Self {
156 Self::EMPTY_REPR
157 }
158
159 #[inline(always)]
161 pub const fn all() -> Self {
162 Self::ALL_REPR
163 }
164
165 #[inline(always)]
171 pub const fn bit_width() -> u32 {
172 T::BIT_WIDTH
173 }
174
175 #[inline(always)]
180 pub const fn variant_count() -> u32 {
181 T::VARIANT_COUNT
182 }
183
184 #[inline(always)]
186 pub fn len(&self) -> usize {
187 self.__priv_repr.count_ones() as usize
188 }
189 #[inline(always)]
191 pub fn is_empty(&self) -> bool {
192 self.__priv_repr.is_empty()
193 }
194 #[inline(always)]
196 pub fn clear(&mut self) {
197 self.__priv_repr = T::Repr::EMPTY;
198 }
199
200 #[inline(always)]
203 pub fn is_disjoint(&self, other: Self) -> bool {
204 (*self & other).is_empty()
205 }
206 #[inline(always)]
209 pub fn is_superset(&self, other: Self) -> bool {
210 (*self & other).__priv_repr == other.__priv_repr
211 }
212 #[inline(always)]
215 pub fn is_subset(&self, other: Self) -> bool {
216 other.is_superset(*self)
217 }
218
219 #[inline(always)]
221 pub fn union(&self, other: Self) -> Self {
222 EnumSet { __priv_repr: self.__priv_repr | other.__priv_repr }
223 }
224 #[inline(always)]
226 pub fn intersection(&self, other: Self) -> Self {
227 EnumSet { __priv_repr: self.__priv_repr & other.__priv_repr }
228 }
229 #[inline(always)]
231 pub fn difference(&self, other: Self) -> Self {
232 EnumSet { __priv_repr: self.__priv_repr.and_not(other.__priv_repr) }
233 }
234 #[inline(always)]
237 pub fn symmetrical_difference(&self, other: Self) -> Self {
238 EnumSet { __priv_repr: self.__priv_repr ^ other.__priv_repr }
239 }
240 #[inline(always)]
242 pub fn complement(&self) -> Self {
243 EnumSet { __priv_repr: !self.__priv_repr & T::ALL_BITS }
244 }
245
246 #[inline(always)]
248 pub fn contains(&self, value: T) -> bool {
249 self.__priv_repr.has_bit(value.enum_into_u32())
250 }
251
252 #[inline(always)]
258 pub fn insert(&mut self, value: T) -> bool {
259 let contains = !self.contains(value);
260 self.__priv_repr.add_bit(value.enum_into_u32());
261 contains
262 }
263 #[inline(always)]
265 pub fn remove(&mut self, value: T) -> bool {
266 let contains = self.contains(value);
267 self.__priv_repr.remove_bit(value.enum_into_u32());
268 contains
269 }
270
271 #[inline(always)]
273 pub fn insert_all(&mut self, other: Self) {
274 self.__priv_repr = self.__priv_repr | other.__priv_repr
275 }
276 #[inline(always)]
278 pub fn remove_all(&mut self, other: Self) {
279 self.__priv_repr = self.__priv_repr.and_not(other.__priv_repr);
280 }
281}
282
283#[doc(hidden)]
284impl<T: EnumSetType> EnumSet<T> {
285 #[deprecated(note = "This method is an internal implementation detail generated by the \
287 `enumset` crate's procedural macro. It should not be used directly.")]
288 #[doc(hidden)]
289 #[allow(non_snake_case)]
290 pub const fn __impl_enumset_internal__const_helper(&self) -> T::ConstHelper {
291 T::CONST_HELPER_INSTANCE
292 }
293
294 #[deprecated(note = "This method is an internal implementation detail generated by the \
296 `enumset` crate's procedural macro. It should not be used directly.")]
297 #[doc(hidden)]
298 #[allow(non_snake_case)]
299 pub const fn __impl_enumset_internal__const_only(self) -> Self {
300 self
301 }
302}
303
304impl<T: EnumSetType> Default for EnumSet<T> {
305 fn default() -> Self {
307 Self::new()
308 }
309}
310
311impl<T: EnumSetType, O: Into<EnumSet<T>>> Sub<O> for EnumSet<T> {
312 type Output = Self;
313 #[inline(always)]
314 fn sub(self, other: O) -> Self::Output {
315 self.difference(other.into())
316 }
317}
318impl<T: EnumSetType, O: Into<EnumSet<T>>> BitAnd<O> for EnumSet<T> {
319 type Output = Self;
320 #[inline(always)]
321 fn bitand(self, other: O) -> Self::Output {
322 self.intersection(other.into())
323 }
324}
325impl<T: EnumSetType, O: Into<EnumSet<T>>> BitOr<O> for EnumSet<T> {
326 type Output = Self;
327 #[inline(always)]
328 fn bitor(self, other: O) -> Self::Output {
329 self.union(other.into())
330 }
331}
332impl<T: EnumSetType, O: Into<EnumSet<T>>> BitXor<O> for EnumSet<T> {
333 type Output = Self;
334 #[inline(always)]
335 fn bitxor(self, other: O) -> Self::Output {
336 self.symmetrical_difference(other.into())
337 }
338}
339
340impl<T: EnumSetType, O: Into<EnumSet<T>>> SubAssign<O> for EnumSet<T> {
341 #[inline(always)]
342 fn sub_assign(&mut self, rhs: O) {
343 *self = *self - rhs;
344 }
345}
346impl<T: EnumSetType, O: Into<EnumSet<T>>> BitAndAssign<O> for EnumSet<T> {
347 #[inline(always)]
348 fn bitand_assign(&mut self, rhs: O) {
349 *self = *self & rhs;
350 }
351}
352impl<T: EnumSetType, O: Into<EnumSet<T>>> BitOrAssign<O> for EnumSet<T> {
353 #[inline(always)]
354 fn bitor_assign(&mut self, rhs: O) {
355 *self = *self | rhs;
356 }
357}
358impl<T: EnumSetType, O: Into<EnumSet<T>>> BitXorAssign<O> for EnumSet<T> {
359 #[inline(always)]
360 fn bitxor_assign(&mut self, rhs: O) {
361 *self = *self ^ rhs;
362 }
363}
364
365impl<T: EnumSetType> Not for EnumSet<T> {
366 type Output = Self;
367 #[inline(always)]
368 fn not(self) -> Self::Output {
369 self.complement()
370 }
371}
372
373impl<T: EnumSetType> From<T> for EnumSet<T> {
374 fn from(t: T) -> Self {
375 EnumSet::only(t)
376 }
377}
378
379impl<T: EnumSetType> PartialEq<T> for EnumSet<T> {
380 fn eq(&self, other: &T) -> bool {
381 self.__priv_repr == EnumSet::only(*other).__priv_repr
382 }
383}
384
385impl<T: EnumSetType + Debug> Debug for EnumSet<T> {
386 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
387 f.write_str("EnumSet(")?;
389 let mut i = self.iter();
390 if let Some(v) = i.next() {
391 v.fmt(f)?;
392 for v in i {
393 f.write_str(" | ")?;
394 v.fmt(f)?;
395 }
396 }
397 f.write_str(")")?;
398 Ok(())
399 }
400}
401impl<T: EnumSetType + Display> Display for EnumSet<T> {
402 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
403 let mut i = self.iter();
404 if let Some(v) = i.next() {
405 v.fmt(f)?;
406 for v in i {
407 f.write_str(" | ")?;
408 v.fmt(f)?;
409 }
410 }
411 Ok(())
412 }
413}
414
415#[cfg(feature = "defmt")]
416impl<T: EnumSetType + defmt::Format> defmt::Format for EnumSet<T> {
417 fn format(&self, f: defmt::Formatter) {
418 let mut i = self.iter();
419 if let Some(v) = i.next() {
420 v.format(f);
421 let l = defmt::intern!(" | ");
422 for v in i {
423 l.format(f);
424 v.format(f);
425 }
426 }
427 }
428}
429
430#[allow(clippy::derived_hash_with_manual_eq)] impl<T: EnumSetType> Hash for EnumSet<T> {
432 fn hash<H: Hasher>(&self, state: &mut H) {
433 self.__priv_repr.hash(state)
434 }
435}
436#[allow(clippy::non_canonical_partial_ord_impl)]
437impl<T: EnumSetType> PartialOrd for EnumSet<T> {
438 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
439 self.__priv_repr.partial_cmp(&other.__priv_repr)
440 }
441}
442impl<T: EnumSetType> Ord for EnumSet<T> {
443 fn cmp(&self, other: &Self) -> Ordering {
444 self.__priv_repr.cmp(&other.__priv_repr)
445 }
446}
447
448#[cfg(feature = "serde")]
449impl<T: EnumSetType> Serialize for EnumSet<T> {
450 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
451 T::serialize(*self, serializer)
452 }
453}
454
455#[cfg(feature = "serde")]
456impl<'de, T: EnumSetType> Deserialize<'de> for EnumSet<T> {
457 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
458 T::deserialize(deserializer)
459 }
460}
461impl<T: EnumSetType> EnumSet<T> {
466 #[deprecated = "Use `EnumSet::empty()` instead."]
470 pub const EMPTY: Self = Self::EMPTY_REPR;
471
472 #[deprecated = "Use `EnumSet::all()` instead."]
476 pub const ALL: Self = Self::ALL_REPR;
477}
478impl<T: EnumSetType + EnumSetTypeWithRepr> EnumSet<T> {
482 #[inline(always)]
490 pub const fn as_repr(&self) -> <T as EnumSetTypeWithRepr>::Repr {
491 self.__priv_repr
492 }
493
494 #[inline(always)]
507 pub unsafe fn from_repr_unchecked(bits: <T as EnumSetTypeWithRepr>::Repr) -> Self {
508 Self { __priv_repr: bits }
509 }
510
511 #[inline(always)]
519 pub fn from_repr(bits: <T as EnumSetTypeWithRepr>::Repr) -> Self {
520 Self::try_from_repr(bits).expect("Bitset contains invalid variants.")
521 }
522
523 #[inline(always)]
531 pub fn try_from_repr(bits: <T as EnumSetTypeWithRepr>::Repr) -> Option<Self> {
532 let mask = Self::all().__priv_repr;
533 if bits.and_not(mask).is_empty() {
534 Some(EnumSet { __priv_repr: bits })
535 } else {
536 None
537 }
538 }
539
540 #[inline(always)]
545 pub fn from_repr_truncated(bits: <T as EnumSetTypeWithRepr>::Repr) -> Self {
546 let mask = Self::all().as_repr();
547 let bits = bits & mask;
548 EnumSet { __priv_repr: bits }
549 }
550}
551
552macro_rules! conversion_impls {
554 (
555 $(for_num!(
556 $underlying:ty, $underlying_str:expr,
557 $from_fn:ident $to_fn:ident $from_fn_opt:ident $to_fn_opt:ident,
558 $from:ident $try_from:ident $from_truncated:ident $from_unchecked:ident,
559 $to:ident $try_to:ident $to_truncated:ident
560 );)*
561 ) => {
562 impl<T: EnumSetType> EnumSet<T> {$(
563 #[doc = "Returns a `"]
564 #[doc = $underlying_str]
565 #[doc = "` representing the elements of this set.\n\nIf the underlying bitset will \
566 not fit in a `"]
567 #[doc = $underlying_str]
568 #[doc = "`, this method will panic."]
569 #[inline(always)]
570 pub fn $to(&self) -> $underlying {
571 self.$try_to().expect("Bitset will not fit into this type.")
572 }
573
574 #[doc = "Tries to return a `"]
575 #[doc = $underlying_str]
576 #[doc = "` representing the elements of this set.\n\nIf the underlying bitset will \
577 not fit in a `"]
578 #[doc = $underlying_str]
579 #[doc = "`, this method will panic."]
580 #[inline(always)]
581 pub fn $try_to(&self) -> Option<$underlying> {
582 EnumSetTypeRepr::$to_fn_opt(&self.__priv_repr)
583 }
584
585 #[doc = "Returns a truncated `"]
586 #[doc = $underlying_str]
587 #[doc = "` representing the elements of this set.\n\nIf the underlying bitset will \
588 not fit in a `"]
589 #[doc = $underlying_str]
590 #[doc = "`, this method will truncate any bits that don't fit."]
591 #[inline(always)]
592 pub fn $to_truncated(&self) -> $underlying {
593 EnumSetTypeRepr::$to_fn(&self.__priv_repr)
594 }
595
596 #[doc = "Constructs a bitset from a `"]
597 #[doc = $underlying_str]
598 #[doc = "`.\n\nIf a bit that doesn't correspond to an enum variant is set, this \
599 method will panic."]
600 #[inline(always)]
601 pub fn $from(bits: $underlying) -> Self {
602 Self::$try_from(bits).expect("Bitset contains invalid variants.")
603 }
604
605 #[doc = "Attempts to constructs a bitset from a `"]
606 #[doc = $underlying_str]
607 #[doc = "`.\n\nIf a bit that doesn't correspond to an enum variant is set, this \
608 method will return `None`."]
609 #[inline(always)]
610 pub fn $try_from(bits: $underlying) -> Option<Self> {
611 let bits = T::Repr::$from_fn_opt(bits);
612 let mask = T::ALL_BITS;
613 bits.and_then(|bits| if bits.and_not(mask).is_empty() {
614 Some(EnumSet { __priv_repr: bits })
615 } else {
616 None
617 })
618 }
619
620 #[doc = "Constructs a bitset from a `"]
621 #[doc = $underlying_str]
622 #[doc = "`, ignoring bits that do not correspond to a variant."]
623 #[inline(always)]
624 pub fn $from_truncated(bits: $underlying) -> Self {
625 let mask = Self::all().$to_truncated();
626 let bits = <T::Repr as EnumSetTypeRepr>::$from_fn(bits & mask);
627 EnumSet { __priv_repr: bits }
628 }
629
630 #[doc = "Constructs a bitset from a `"]
631 #[doc = $underlying_str]
632 #[doc = "`, without checking for invalid bits."]
633 #[inline(always)]
640 pub unsafe fn $from_unchecked(bits: $underlying) -> Self {
641 EnumSet { __priv_repr: <T::Repr as EnumSetTypeRepr>::$from_fn(bits) }
642 }
643 )*}
644 }
645}
646conversion_impls! {
647 for_num!(u8, "u8",
648 from_u8 to_u8 from_u8_opt to_u8_opt,
649 from_u8 try_from_u8 from_u8_truncated from_u8_unchecked,
650 as_u8 try_as_u8 as_u8_truncated);
651 for_num!(u16, "u16",
652 from_u16 to_u16 from_u16_opt to_u16_opt,
653 from_u16 try_from_u16 from_u16_truncated from_u16_unchecked,
654 as_u16 try_as_u16 as_u16_truncated);
655 for_num!(u32, "u32",
656 from_u32 to_u32 from_u32_opt to_u32_opt,
657 from_u32 try_from_u32 from_u32_truncated from_u32_unchecked,
658 as_u32 try_as_u32 as_u32_truncated);
659 for_num!(u64, "u64",
660 from_u64 to_u64 from_u64_opt to_u64_opt,
661 from_u64 try_from_u64 from_u64_truncated from_u64_unchecked,
662 as_u64 try_as_u64 as_u64_truncated);
663 for_num!(u128, "u128",
664 from_u128 to_u128 from_u128_opt to_u128_opt,
665 from_u128 try_from_u128 from_u128_truncated from_u128_unchecked,
666 as_u128 try_as_u128 as_u128_truncated);
667 for_num!(usize, "usize",
668 from_usize to_usize from_usize_opt to_usize_opt,
669 from_usize try_from_usize from_usize_truncated from_usize_unchecked,
670 as_usize try_as_usize as_usize_truncated);
671}
672
673impl<T: EnumSetType> EnumSet<T> {
674 pub fn as_array<const O: usize>(&self) -> [u64; O] {
678 self.try_as_array()
679 .expect("Bitset will not fit into this type.")
680 }
681
682 pub fn try_as_array<const O: usize>(&self) -> Option<[u64; O]> {
687 self.__priv_repr.to_u64_array_opt()
688 }
689
690 pub fn as_array_truncated<const O: usize>(&self) -> [u64; O] {
695 self.__priv_repr.to_u64_array()
696 }
697
698 pub fn from_array<const O: usize>(v: [u64; O]) -> Self {
702 Self::try_from_array(v).expect("Bitset contains invalid variants.")
703 }
704
705 pub fn try_from_array<const O: usize>(bits: [u64; O]) -> Option<Self> {
709 let bits = T::Repr::from_u64_array_opt::<O>(bits);
710 let mask = T::ALL_BITS;
711 bits.and_then(|bits| {
712 if bits.and_not(mask).is_empty() {
713 Some(EnumSet { __priv_repr: bits })
714 } else {
715 None
716 }
717 })
718 }
719
720 pub fn from_array_truncated<const O: usize>(bits: [u64; O]) -> Self {
722 let bits = T::Repr::from_u64_array(bits) & T::ALL_BITS;
723 EnumSet { __priv_repr: bits }
724 }
725
726 #[inline(always)]
734 pub unsafe fn from_array_unchecked<const O: usize>(bits: [u64; O]) -> Self {
735 EnumSet { __priv_repr: T::Repr::from_u64_array(bits) }
736 }
737
738 #[cfg(feature = "alloc")]
740 #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
741 pub fn to_vec(&self) -> alloc::vec::Vec<u64> {
742 let mut vec = alloc::vec![0; T::Repr::PREFERRED_ARRAY_LEN];
743 self.__priv_repr.to_u64_slice(&mut vec);
744 vec
745 }
746
747 pub fn copy_into_slice(&self, data: &mut [u64]) {
751 self.try_copy_into_slice(data)
752 .expect("Bitset will not fit into slice.")
753 }
754
755 #[must_use]
760 pub fn try_copy_into_slice(&self, data: &mut [u64]) -> Option<()> {
761 self.__priv_repr.to_u64_slice_opt(data)
762 }
763
764 pub fn copy_into_slice_truncated(&self, data: &mut [u64]) {
769 self.__priv_repr.to_u64_slice(data)
770 }
771
772 pub fn from_slice(v: &[u64]) -> Self {
776 Self::try_from_slice(v).expect("Bitset contains invalid variants.")
777 }
778
779 pub fn try_from_slice(bits: &[u64]) -> Option<Self> {
783 let bits = T::Repr::from_u64_slice_opt(bits);
784 let mask = T::ALL_BITS;
785 bits.and_then(|bits| {
786 if bits.and_not(mask).is_empty() {
787 Some(EnumSet { __priv_repr: bits })
788 } else {
789 None
790 }
791 })
792 }
793
794 pub fn from_slice_truncated(bits: &[u64]) -> Self {
796 let bits = T::Repr::from_u64_slice(bits) & T::ALL_BITS;
797 EnumSet { __priv_repr: bits }
798 }
799
800 #[inline(always)]
808 pub unsafe fn from_slice_unchecked(bits: &[u64]) -> Self {
809 EnumSet { __priv_repr: T::Repr::from_u64_slice(bits) }
810 }
811}
812#[derive(Clone, Debug)]
817pub struct EnumSetIter<T: EnumSetType> {
818 iter: <T::Repr as EnumSetTypeRepr>::Iter,
819}
820impl<T: EnumSetType> EnumSetIter<T> {
821 fn new(set: EnumSet<T>) -> EnumSetIter<T> {
822 EnumSetIter { iter: set.__priv_repr.iter() }
823 }
824}
825
826impl<T: EnumSetType> EnumSet<T> {
827 pub fn iter(&self) -> EnumSetIter<T> {
833 EnumSetIter::new(*self)
834 }
835}
836
837impl<T: EnumSetType> Iterator for EnumSetIter<T> {
838 type Item = T;
839
840 fn next(&mut self) -> Option<Self::Item> {
841 self.iter.next().map(|x| unsafe { T::enum_from_u32(x) })
842 }
843 fn size_hint(&self) -> (usize, Option<usize>) {
844 self.iter.size_hint()
845 }
846}
847
848impl<T: EnumSetType> DoubleEndedIterator for EnumSetIter<T> {
849 fn next_back(&mut self) -> Option<Self::Item> {
850 self.iter
851 .next_back()
852 .map(|x| unsafe { T::enum_from_u32(x) })
853 }
854}
855
856impl<T: EnumSetType> ExactSizeIterator for EnumSetIter<T> {}
857
858impl<T: EnumSetType> Extend<T> for EnumSet<T> {
859 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
860 iter.into_iter().for_each(|v| {
861 self.insert(v);
862 });
863 }
864}
865
866impl<T: EnumSetType> FromIterator<T> for EnumSet<T> {
867 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
868 let mut set = EnumSet::default();
869 set.extend(iter);
870 set
871 }
872}
873
874impl<T: EnumSetType> Extend<EnumSet<T>> for EnumSet<T> {
875 fn extend<I: IntoIterator<Item = EnumSet<T>>>(&mut self, iter: I) {
876 iter.into_iter().for_each(|v| {
877 self.insert_all(v);
878 });
879 }
880}
881
882impl<T: EnumSetType> FromIterator<EnumSet<T>> for EnumSet<T> {
883 fn from_iter<I: IntoIterator<Item = EnumSet<T>>>(iter: I) -> Self {
884 let mut set = EnumSet::default();
885 set.extend(iter);
886 set
887 }
888}
889
890impl<T: EnumSetType> IntoIterator for EnumSet<T> {
891 type Item = T;
892 type IntoIter = EnumSetIter<T>;
893
894 fn into_iter(self) -> Self::IntoIter {
895 self.iter()
896 }
897}
898impl<T: EnumSetType> Sum for EnumSet<T> {
899 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
900 iter.fold(EnumSet::empty(), |a, v| a | v)
901 }
902}
903impl<'a, T: EnumSetType> Sum<&'a EnumSet<T>> for EnumSet<T> {
904 fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
905 iter.fold(EnumSet::empty(), |a, v| a | *v)
906 }
907}
908impl<T: EnumSetType> Sum<T> for EnumSet<T> {
909 fn sum<I: Iterator<Item = T>>(iter: I) -> Self {
910 iter.fold(EnumSet::empty(), |a, v| a | v)
911 }
912}
913impl<'a, T: EnumSetType> Sum<&'a T> for EnumSet<T> {
914 fn sum<I: Iterator<Item = &'a T>>(iter: I) -> Self {
915 iter.fold(EnumSet::empty(), |a, v| a | *v)
916 }
917}
918