enumset/
impl_set_mixed.rs1use crate::repr::EnumSetTypeRepr;
2use crate::traits::{EnumSetType, EnumSetTypePrivate};
3use crate::{EnumSet, 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 serde::{Deserialize, Serialize};
14
15#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
17pub enum MixedValue<T: EnumSetType> {
18 Valid(T),
20 Invalid(u32),
22}
23impl<T: EnumSetType> MixedValue<T> {
24 fn from_bit(b: u32) -> MixedValue<T> {
25 if T::ALL_BITS.has_bit(b) {
26 unsafe { MixedValue::Valid(T::enum_from_u32(b)) }
27 } else {
28 MixedValue::Invalid(b)
29 }
30 }
31}
32impl<T: EnumSetType> Debug for MixedValue<T>
33where T: Debug
34{
35 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
36 match self {
37 MixedValue::Valid(v) => v.fmt(f),
38 MixedValue::Invalid(b) => write!(f, "[{b}]"),
39 }
40 }
41}
42impl<T: EnumSetType> Display for MixedValue<T>
43where T: Display
44{
45 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
46 match self {
47 MixedValue::Valid(v) => v.fmt(f),
48 MixedValue::Invalid(b) => write!(f, "[{b}]"),
49 }
50 }
51}
52#[cfg(feature = "defmt")]
53impl<T: EnumSetType + defmt::Format> defmt::Format for MixedValue<T> {
54 fn format(&self, f: defmt::Formatter) {
55 match self {
56 MixedValue::Valid(v) => defmt::write!(f, "{}", v),
57 MixedValue::Invalid(b) => defmt::write!(f, "[{}]", b),
58 }
59 }
60}
61
62#[derive(Copy, Clone, PartialEq, Eq)]
85#[repr(transparent)]
86pub struct MixedEnumSet<T: EnumSetTypeWithRepr> {
87 pub(crate) repr: <T as EnumSetTypePrivate>::Repr,
88}
89
90impl<T: EnumSetTypeWithRepr> MixedEnumSet<T> {
92 const EMPTY_REPR: Self = MixedEnumSet { repr: <T as EnumSetTypePrivate>::Repr::EMPTY };
93 const ALL_REPR: Self = MixedEnumSet { repr: T::ALL_BITS };
94
95 #[inline(always)]
97 pub const fn new() -> Self {
98 Self::EMPTY_REPR
99 }
100
101 #[inline(always)]
105 pub const fn empty() -> Self {
106 Self::EMPTY_REPR
107 }
108
109 #[inline(always)]
111 pub const fn all() -> Self {
112 Self::ALL_REPR
113 }
114
115 #[inline(always)]
117 pub const fn variant_count() -> u32 {
118 T::VARIANT_COUNT
119 }
120
121 set_common_methods!(T, <T as EnumSetTypePrivate>::Repr, impl Into<Self>);
122
123 #[inline(always)]
127 pub fn complement(&self) -> Self {
128 Self { repr: !self.repr & T::ALL_BITS }
129 }
130
131 #[inline(always)]
135 pub fn full_complement(&self) -> Self {
136 Self { repr: !self.repr }
137 }
138
139 #[inline(always)]
141 pub fn valid_len(&self) -> usize {
142 (self.repr & T::ALL_BITS).count_ones() as usize
143 }
144
145 #[inline(always)]
147 pub fn has_unknown_bits(&self) -> bool {
148 !(self.repr & !T::ALL_BITS).is_empty()
149 }
150
151 #[inline(always)]
153 pub fn has_bit(&self, value: u32) -> bool {
154 self.repr.has_bit(value)
155 }
156
157 #[inline(always)]
163 pub fn insert_bit(&mut self, value: u32) -> bool {
164 let contains = !self.has_bit(value);
165 self.repr.add_bit(value);
166 contains
167 }
168
169 #[inline(always)]
171 pub fn remove_bit(&mut self, value: u32) -> bool {
172 let contains = self.has_bit(value);
173 self.repr.remove_bit(value);
174 contains
175 }
176
177 #[inline(always)]
179 pub fn insert_all(&mut self, other: impl Into<Self>) {
180 self.repr = self.repr | other.into().repr
181 }
182
183 #[inline(always)]
185 pub fn remove_all(&mut self, other: impl Into<Self>) {
186 self.repr = self.repr.and_not(other.into().repr);
187 }
188}
189
190set_common_impls!(MixedEnumSet, EnumSetTypeWithRepr);
191
192impl<T: EnumSetTypeWithRepr> PartialEq<MixedEnumSet<T>> for EnumSet<T> {
193 fn eq(&self, other: &MixedEnumSet<T>) -> bool {
194 self.repr == other.repr
195 }
196}
197impl<T: EnumSetTypeWithRepr> PartialEq<EnumSet<T>> for MixedEnumSet<T> {
198 fn eq(&self, other: &EnumSet<T>) -> bool {
199 self.repr == other.repr
200 }
201}
202
203#[cfg(feature = "defmt")]
204impl<T: EnumSetTypeWithRepr + defmt::Format> defmt::Format for MixedEnumSet<T> {
205 fn format(&self, f: defmt::Formatter) {
206 let mut i = self.iter();
207 if let Some(v) = i.next() {
208 defmt::write!(f, "{}", v);
209 for v in i {
210 defmt::write!(f, " | {}", v);
211 }
212 }
213 }
214}
215
216#[cfg(feature = "serde")]
217impl<T: EnumSetTypeWithRepr> Serialize for MixedEnumSet<T>
218where <T as EnumSetTypeWithRepr>::Repr: Serialize
219{
220 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
221 self.repr.serialize(serializer)
222 }
223}
224
225#[cfg(feature = "serde")]
226impl<'de, T: EnumSetTypeWithRepr> Deserialize<'de> for MixedEnumSet<T>
227where <T as EnumSetTypeWithRepr>::Repr: Deserialize<'de>
228{
229 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
230 <T as EnumSetTypeWithRepr>::Repr::deserialize(deserializer).map(|x| Self { repr: x })
231 }
232}
233impl<T: EnumSetTypeWithRepr> MixedEnumSet<T> {
237 #[inline(always)]
242 pub const fn as_repr(&self) -> <T as EnumSetTypeWithRepr>::Repr {
243 self.repr
244 }
245
246 #[inline(always)]
248 pub fn from_repr(bits: <T as EnumSetTypeWithRepr>::Repr) -> Self {
249 Self { repr: bits }
250 }
251
252 #[inline(always)]
254 pub fn from_repr_truncated(bits: <T as EnumSetTypeWithRepr>::Repr) -> Self {
255 let mask = Self::all().as_repr();
256 let bits = bits & mask;
257 MixedEnumSet { repr: bits }
258 }
259
260 pub fn as_enumset(&self) -> EnumSet<T> {
264 self.try_as_enumset()
265 .expect("Bitset contains invalid variants.")
266 }
267
268 pub fn try_as_enumset(&self) -> Option<EnumSet<T>> {
272 if self.has_unknown_bits() {
273 None
274 } else {
275 Some(EnumSet { repr: self.repr })
276 }
277 }
278
279 pub fn as_enumset_truncate(&self) -> EnumSet<T> {
282 EnumSet { repr: self.repr & T::ALL_BITS }
283 }
284}
285
286impl<T: EnumSetTypeWithRepr, const N: usize> From<[T; N]> for MixedEnumSet<T> {
287 fn from(value: [T; N]) -> Self {
288 let mut new = MixedEnumSet::new();
289 for elem in value {
290 new.insert(elem);
291 }
292 new
293 }
294}
295
296impl<T: EnumSetTypeWithRepr> From<EnumSet<T>> for MixedEnumSet<T> {
297 fn from(value: EnumSet<T>) -> Self {
298 MixedEnumSet { repr: value.repr }
299 }
300}
301#[derive(Clone, Debug)]
306pub struct MixedEnumSetIter<T: EnumSetType> {
307 iter: <T::Repr as EnumSetTypeRepr>::Iter,
308}
309impl<T: EnumSetTypeWithRepr> MixedEnumSetIter<T> {
310 fn new(set: MixedEnumSet<T>) -> MixedEnumSetIter<T> {
311 MixedEnumSetIter { iter: set.repr.iter() }
312 }
313}
314
315impl<T: EnumSetTypeWithRepr> MixedEnumSet<T> {
316 pub fn iter(&self) -> MixedEnumSetIter<T> {
322 MixedEnumSetIter::new(*self)
323 }
324}
325
326impl<T: EnumSetTypeWithRepr> Iterator for MixedEnumSetIter<T> {
327 type Item = MixedValue<T>;
328
329 fn next(&mut self) -> Option<Self::Item> {
330 self.iter.next().map(|x| MixedValue::from_bit(x))
331 }
332 fn size_hint(&self) -> (usize, Option<usize>) {
333 self.iter.size_hint()
334 }
335}
336impl<T: EnumSetTypeWithRepr> DoubleEndedIterator for MixedEnumSetIter<T> {
337 fn next_back(&mut self) -> Option<Self::Item> {
338 self.iter.next_back().map(|x| MixedValue::from_bit(x))
339 }
340}
341impl<T: EnumSetTypeWithRepr> ExactSizeIterator for MixedEnumSetIter<T> {}
342
343set_iterator_impls!(MixedEnumSet, EnumSetTypeWithRepr);
344
345impl<T: EnumSetTypeWithRepr> IntoIterator for MixedEnumSet<T> {
346 type Item = MixedValue<T>;
347 type IntoIter = MixedEnumSetIter<T>;
348
349 fn into_iter(self) -> Self::IntoIter {
350 self.iter()
351 }
352}
353
354impl<T: EnumSetTypeWithRepr> Extend<EnumSet<T>> for MixedEnumSet<T> {
355 fn extend<I: IntoIterator<Item = EnumSet<T>>>(&mut self, iter: I) {
356 iter.into_iter().for_each(|v| {
357 self.insert_all(v);
358 });
359 }
360}
361
362impl<'a, T: EnumSetTypeWithRepr> Extend<&'a EnumSet<T>> for MixedEnumSet<T> {
363 fn extend<I: IntoIterator<Item = &'a EnumSet<T>>>(&mut self, iter: I) {
364 iter.into_iter().for_each(|v| {
365 self.insert_all(*v);
366 });
367 }
368}
369
370impl<T: EnumSetTypeWithRepr> FromIterator<EnumSet<T>> for MixedEnumSet<T> {
371 fn from_iter<I: IntoIterator<Item = EnumSet<T>>>(iter: I) -> Self {
372 let mut set = MixedEnumSet::default();
373 set.extend(iter);
374 set
375 }
376}
377
378impl<'a, T: 'a + EnumSetTypeWithRepr> FromIterator<&'a EnumSet<T>> for MixedEnumSet<T> {
379 fn from_iter<I: IntoIterator<Item = &'a EnumSet<T>>>(iter: I) -> Self {
380 let mut set = MixedEnumSet::default();
381 set.extend(iter);
382 set
383 }
384}
385
386impl<'a, T: EnumSetTypeWithRepr> Sum<EnumSet<T>> for MixedEnumSet<T> {
387 fn sum<I: Iterator<Item = EnumSet<T>>>(iter: I) -> Self {
388 iter.fold(MixedEnumSet::empty(), |a, v| a | v)
389 }
390}
391
392impl<'a, T: EnumSetTypeWithRepr> Sum<&'a EnumSet<T>> for MixedEnumSet<T> {
393 fn sum<I: Iterator<Item = &'a EnumSet<T>>>(iter: I) -> Self {
394 iter.fold(MixedEnumSet::empty(), |a, v| a | *v)
395 }
396}
397