1#![doc = include_str!("../README.md")]
2#![no_std]
3
4use core::{
5    fmt::{Debug, Display},
6    marker::PhantomData,
7    ops::{
8        Add, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, Mul, Rem, Shl,
9        ShlAssign, Shr, ShrAssign, Sub,
10    },
11};
12
13use num_traits::{Bounded, Num, One, Zero};
14#[doc(hidden)]
16#[cfg(feature = "serde")]
17pub use serde;
18
19mod types;
20
21pub use types::{
22    i10, i11, i12, i13, i14, i15, i17, i18, i19, i2, i20, i21, i22, i23, i24, i25, i26, i27, i28,
23    i29, i3, i30, i31, i33, i34, i35, i36, i37, i38, i39, i4, i40, i41, i42, i43, i44, i45, i46,
24    i47, i48, i49, i5, i50, i51, i52, i53, i54, i55, i56, i57, i58, i59, i6, i60, i61, i62, i63,
25    i7, i9, u1, u10, u11, u12, u13, u14, u15, u17, u18, u19, u2, u20, u21, u22, u23, u24, u25, u26,
26    u27, u28, u29, u3, u30, u31, u33, u34, u35, u36, u37, u38, u39, u4, u40, u41, u42, u43, u44,
27    u45, u46, u47, u48, u49, u5, u50, u51, u52, u53, u54, u55, u56, u57, u58, u59, u6, u60, u61,
28    u62, u63, u7, u9,
29};
30
31#[repr(transparent)]
42#[derive(Copy, Clone, PartialOrd, PartialEq, Eq, Ord, Hash)]
43pub struct UnsafeStorage<T>(T);
44
45impl<T> UnsafeStorage<T> {
46    pub const unsafe fn new_unsafe(inner: T) -> Self {
52        Self(inner)
53    }
54
55    pub unsafe fn as_ref_mut(&mut self) -> &mut T {
61        &mut self.0
62    }
63}
64
65impl<T> AsRef<T> for UnsafeStorage<T> {
66    fn as_ref(&self) -> &T {
68        &self.0
69    }
70}
71
72impl<T: Copy> UnsafeStorage<T> {
73    pub const fn inner(&self) -> T {
75        self.0
76    }
77}
78
79pub unsafe trait BitCount {
90    const COUNT: usize;
92}
93
94pub trait FieldStorage {
96    type StoredType;
98    fn inner_raw(self) -> Self::StoredType;
100}
101
102pub trait BitsFitIn<T> {
111    fn fit(self) -> T;
113}
114
115pub unsafe trait ValidCheck<P> {
129    const ALWAYS_VALID: bool = false;
133    fn is_valid(_input: P) -> bool {
136        true
137    }
138}
139
140pub struct GetSet<'a, P, T, const START: usize, const STOP: usize> {
142    parent: &'a mut P,
144    _phantom: PhantomData<&'a mut T>,
146}
147
148impl<'a, P, T, const START: usize, const STOP: usize> GetSet<'a, P, T, START, STOP> {
149    pub const fn start(&self) -> usize {
151        START
152    }
153
154    pub const fn stop(&self) -> usize {
156        STOP
157    }
158}
159
160impl<
161        'a,
162        P: Num + Bounded + ShlAssign<usize> + ShrAssign<usize> + BitCount,
163        T,
164        const START: usize,
165        const STOP: usize,
166    > GetSet<'a, P, T, START, STOP>
167{
168    pub fn new(parent: &'a mut P) -> Self {
171        Self {
172            parent,
173            _phantom: PhantomData::default(),
174        }
175    }
176
177    #[allow(clippy::unused_self)]
183    fn mask(&self) -> P {
184        let num_bits = P::COUNT;
185        let mut max_value = P::max_value();
186        let keep_bits = STOP - START + 1;
187
188        max_value >>= num_bits - keep_bits;
189        max_value
190    }
191}
192
193impl<
194        'a,
195        P: Num
196            + Shl<usize, Output = P>
197            + Shr<usize, Output = P>
198            + ShlAssign<usize>
199            + ShrAssign<usize>
200            + Bounded
201            + BitAnd<Output = P>
202            + Copy
203            + BitCount,
204        T: ValidCheck<P>,
205        const START: usize,
206        const STOP: usize,
207    > GetSet<'a, P, T, START, STOP>
208{
209    pub fn get(&self) -> T {
211        let section = self.get_raw();
212        unsafe { core::mem::transmute_copy(§ion) }
216    }
217
218    pub fn is_valid(&self) -> bool {
221        let section = self.get_raw();
222        T::is_valid(section)
223    }
224
225    pub fn get_raw(&self) -> P {
228        let parent = *self.parent;
229        let mask = self.mask();
230        (parent >> START) & mask
231    }
232}
233
234impl<'a, P, T, const START: usize, const STOP: usize> GetSet<'a, P, T, START, STOP>
235where
236    T: FieldStorage + BitsFitIn<P>,
237    P: Num
238        + Shl<usize, Output = P>
239        + Copy
240        + BitOrAssign
241        + BitXorAssign
242        + BitAnd<Output = P>
243        + ShlAssign<usize>
244        + ShrAssign<usize>
245        + PartialOrd
246        + Bounded
247        + Sized
248        + BitCount,
249{
250    pub fn set(&mut self, value: T) {
252        unsafe { self.set_raw(value.fit()) }
256    }
257
258    pub unsafe fn set_raw(&mut self, value: P) {
263        let mask = self.mask();
264        let mask_shifted = mask << START;
265
266        *self.parent |= mask_shifted;
268        *self.parent ^= mask_shifted;
269
270        let to_set = value & mask;
271        *self.parent |= to_set << START;
272    }
273}
274
275pub trait BitStruct<const ALWAYS_VALID: bool> {
279    type Kind;
281    unsafe fn from_unchecked(value: Self::Kind) -> Self;
294}
295
296pub trait BitStructExt: BitStruct<true> {
299    fn exact_from(value: Self::Kind) -> Self;
301}
302
303impl<T: BitStruct<true>> BitStructExt for T {
304    fn exact_from(value: Self::Kind) -> Self {
305        unsafe { Self::from_unchecked(value) }
309    }
310}
311
312#[doc(hidden)]
313#[macro_export]
314macro_rules! impl_fields {
315    ($on: expr, $kind: ty =>[$($first_field_meta: meta),*], $head_field: ident, $head_actual: ty $(, [$($field_meta: meta),*], $field: ident, $actual: ty)*) => {
316        $(#[$first_field_meta])*
317        pub fn $head_field(&mut self) -> $crate::GetSet<'_, $kind, $head_actual, {$on - <$head_actual as $crate::BitCount>::COUNT}, {$on - 1}> {
318            $crate::GetSet::new(unsafe {self.0.as_ref_mut()})
319        }
320
321        $crate::impl_fields!($on - <$head_actual as $crate::BitCount>::COUNT, $kind => $([$($field_meta),*], $field, $actual),*);
322    };
323    ($on: expr, $kind: ty =>) => {};
324}
325
326#[doc(hidden)]
328#[macro_export]
329macro_rules! bit_struct_impl {
330    (
331        $(#[$meta: meta])*
332        $struct_vis: vis struct $name: ident ($kind: ty) {
333        $(
334            $(#[$field_meta: meta])*
335            $field: ident: $actual: ty
336        ),* $(,)?
337        }
338    ) => {
339
340        impl $name {
341
342            pub unsafe fn empty() -> Self {
344                unsafe { Self::from_unchecked(<$kind as $crate::BitStructZero>::bs_zero()) }
345            }
346
347            #[doc = concat!("Returns a valid representation for [`", stringify!($name), "`] where all values are")]
348            pub fn of_defaults() -> Self {
353                let mut res = unsafe { Self::from_unchecked(<$kind as $crate::BitStructZero>::bs_zero()) };
354                $(
355                    res.$field().set(Default::default());
356                )*
357                res
358            }
359        }
360
361        impl ::core::fmt::Debug for $name {
362            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> core::fmt::Result {
363                let mut copied = *self;
364                f.debug_struct(stringify!($name))
365                    $(
366                        .field(stringify!($field), &copied.$field().get())
367                    )*
368                    .finish()
369            }
370        }
371    };
372}
373
374#[doc(hidden)]
376#[macro_export]
377#[cfg(not(feature = "serde"))]
378macro_rules! bit_struct_serde_impl {
379    (
380        $(#[$meta:meta])*
381        $struct_vis:vis struct
382        $name:ident($kind:ty) { $($(#[$field_meta:meta])* $field:ident : $actual:ty),* $(,)? }
383    ) => {};
384}
385#[doc(hidden)]
387#[macro_export]
388#[cfg(feature = "serde")]
389macro_rules! bit_struct_serde_impl {
390    (
391        $(#[$meta:meta])*
392        $struct_vis: vis struct $name: ident ($kind: ty) {
393        $(
394            $(#[$field_meta:meta])*
395            $field: ident: $actual: ty
396        ),* $(,)?
397        }
398    ) => {
399        #[allow(clippy::used_underscore_binding)]
400        impl $crate::serde::Serialize for $name {
401            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: $crate::serde::Serializer {
402                use $crate::serde::ser::SerializeStruct;
403
404                let mut v = *self;
405
406                let mut serializer = serializer.serialize_struct(
407                    stringify!($name),
408                    $crate::count_idents!( 0, [$( $field ),*] ),
409                )?;
410                $(
411                    serializer.serialize_field(
412                        stringify!($field),
413                        &v.$field().get()
414                    )?;
415                )*
416                serializer.end()
417            }
418        }
419
420        #[allow(clippy::used_underscore_binding)]
421        impl<'de> $crate::serde::Deserialize<'de> for $name {
422            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: $crate::serde::Deserializer<'de> {
423
424                use $crate::serde::de::{self, Deserialize, Deserializer, MapAccess, SeqAccess, Visitor};
425                use ::core::fmt;
426
427                const FIELDS: &'static [&'static str] = &[ $( stringify!( $field ) ),* ];
428
429                #[allow(non_camel_case_types)]
430                enum Fields { $( $field ),* }
431                impl<'de> Deserialize<'de> for Fields {
432                    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
433                        struct FieldVisitor;
434                        impl<'de> Visitor<'de> for FieldVisitor {
435                            type Value = Fields;
436
437                            fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
438                                f.write_str(stringify!( $( $field ),* ))
439                            }
440
441                            fn visit_str<E: de::Error>(self, value: &str) -> Result<Fields, E> {
442                                match value {
443                                    $( stringify!( $field ) => Ok(Fields::$field), )*
444                                    _ => Err(de::Error::unknown_field(value, FIELDS)),
445                                }
446                            }
447                        }
448
449                        deserializer.deserialize_identifier(FieldVisitor)
450                    }
451                }
452
453                struct BitStructVisitor;
454                impl<'de> Visitor<'de> for BitStructVisitor {
455                    type Value = $name;
456
457                    fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
458                        f.write_str(concat!("struct ", stringify!($name)))
459                    }
460
461                    fn visit_map<V: MapAccess<'de>>(self, mut map: V) -> Result<$name, V::Error> {
462                        $( let mut $field: Option<$actual> = None; )*
463                        while let Some(key) = map.next_key::<Fields>()? {
464                            match key {
465                                $( Fields::$field => {
466                                    if $field.is_some() {
467                                        return Err(de::Error::duplicate_field(stringify!($field)));
468                                    }
469                                    $field = Some(map.next_value()?);
470                                },)*
471                            }
472                        }
473                        $(
474                            let $field = $field.ok_or_else(|| de::Error::missing_field(stringify!($field)))?;
475                        )*
476                        Ok($name::new( $( $field ),* ))
477                    }
478
479                    fn visit_seq<V: SeqAccess<'de>>(self, mut seq: V) -> Result<$name, V::Error> {
480                        let mut count = 0;
481                        $(
482                            let $field = seq.next_element()?
483                                .ok_or_else(|| de::Error::invalid_length(count, &self))?;
484                            count += 1;
485                        )*
486                        Ok($name::new( $( $field ),* ))
487                    }
488                }
489                deserializer.deserialize_struct(stringify!($name), FIELDS, BitStructVisitor)
490            }
491        }
492    }
493}
494
495pub trait BitStructZero: Zero {
497    fn bs_zero() -> Self {
499        Self::zero()
500    }
501}
502
503impl<T: Zero> BitStructZero for T {}
504
505#[allow(clippy::needless_doctest_main)]
508#[macro_export]
595macro_rules! bit_struct {
596    (
597        $(
598        $(#[$meta:meta])*
599        $struct_vis: vis struct $name: ident ($kind: ty) {
600        $(
601            $(#[$field_meta:meta])*
602            $field: ident: $actual: ty
603        ),* $(,)?
604        }
605        )*
606    ) => {
607        $(
608        $(#[$meta])*
609        #[derive(Copy, Clone, PartialOrd, PartialEq, Eq, Ord, Hash)]
610        pub struct $name($crate::UnsafeStorage<$kind>);
611
612        $crate::bit_struct_serde_impl! {
613            $(#[$meta])*
614            $struct_vis struct $name ($kind) {
615            $(
616                $(#[$field_meta])*
617                $field: $actual
618            ),*
619            }
620        }
621
622        #[allow(clippy::used_underscore_binding)]
623        impl TryFrom<$kind> for $name {
624            type Error = ();
625            fn try_from(elem: $kind) -> Result<$name, ()> {
626                let mut res = unsafe{Self::from_unchecked(elem)};
627                $(
628                    if !res.$field().is_valid() {
629                        return Err(());
630                    }
631                )*
632                Ok(res)
633            }
634        }
635
636        #[allow(clippy::used_underscore_binding)]
637        impl $crate::BitStruct<{$(<$actual as $crate::ValidCheck<$kind>>::ALWAYS_VALID &&)* true}> for $name {
638            type Kind = $kind;
639
640            unsafe fn from_unchecked(inner: $kind) -> Self {
641               Self(unsafe {$crate::UnsafeStorage::new_unsafe(inner)})
642            }
643        }
644
645        #[allow(clippy::used_underscore_binding)]
646        impl $name {
647
648            unsafe fn from_unchecked(inner: $kind) -> Self {
649               Self(unsafe {$crate::UnsafeStorage::new_unsafe(inner)})
650            }
651
652            #[allow(clippy::too_many_arguments)]
653            pub fn new($($field: $actual),*) -> Self {
654                let mut res = unsafe { Self::from_unchecked(<$kind as $crate::BitStructZero>::bs_zero()) };
655                $(
656                    res.$field().set($field);
657                )*
658                res
659            }
660
661            pub fn raw(self) -> $kind {
662                self.0.inner()
663            }
664
665            $crate::impl_fields!(<$kind as $crate::BitCount>::COUNT, $kind => $([$($field_meta),*], $field, $actual),*);
666        }
667
668        )*
669
670        $(
671        $crate::bit_struct_impl!(
672        $(#[$meta])*
673        $struct_vis struct $name ($kind) {
674        $(
675            $(#[$field_meta])*
676            $field: $actual
677        ),*
678        }
679
680        );
681        )*
682    };
683}
684
685#[doc(hidden)]
686#[macro_export]
687macro_rules! count_idents {
688    ($on: expr, [$head: ident $(,$xs: ident)*]) => {
689        $crate::count_idents!($on + 1, [$($xs),*])
690    };
691    ($on: expr, []) => {
692        $on
693    };
694}
695
696pub const fn bits(num: usize) -> usize {
708    const fn helper(count: usize, on: usize) -> usize {
710        if on > 0 {
713            helper(count + 1, on >> 1)
714        } else {
715            count
716        }
717    }
718
719    helper(0, num)
720}
721
722#[doc(hidden)]
724#[cfg(not(feature = "serde"))]
725#[macro_export]
726macro_rules! enum_serde_impl {
727    ($enum_vis:vis $name:ident { $fst_field:ident $(, $field:ident)* }) => {};
728}
729
730#[doc(hidden)]
732#[cfg(feature = "serde")]
733#[macro_export]
734macro_rules! enum_serde_impl {
735    ($name:ident { $($field:ident),* }) => {
736        impl $crate::serde::Serialize for $name {
737            fn serialize<S: $crate::serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
738                match self {
739                    $(
740                        Self::$field => {
741                            serializer.serialize_unit_variant(
742                                stringify!($name),
743                                *self as u32,
744                                stringify!($field),
745                            )
746                        },
747                    )*
748                }
749            }
750        }
751        impl<'de> $crate::serde::Deserialize<'de> for $name {
752            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: $crate::serde::Deserializer<'de> {
753                use ::core::{fmt, result::Result::{self, Ok, Err}, convert::TryFrom};
754                use $crate::serde::de::{Deserialize, Deserializer, EnumAccess, VariantAccess, Visitor};
755
756                #[repr(u64)]
757                enum Variants { $( $field ),* }
758                impl TryFrom<u64> for Variants {
759                    type Error = ();
760
761                    fn try_from(v: u64) -> Result<Self, Self::Error> {
762                        if v < $crate::count_idents!(0, [$( $field ),*]) {
763                            unsafe { core::mem::transmute(v) }
767                        } else {
768                            Err(())
769                        }
770                    }
771                }
772                impl<'de> Deserialize<'de> for Variants {
773                    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
774                        struct VariantsVisitor;
775                        impl<'de> Visitor<'de> for VariantsVisitor {
776                            type Value = Variants;
777                            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
778                                formatter.write_str("variant identifier")
779                            }
780
781                            fn visit_u64<E: $crate::serde::de::Error>(self, value: u64) -> Result<Self::Value, E> {
782                                Variants::try_from(value)
783                                    .map_err(|()| $crate::serde::de::Error::invalid_value(
784                                        $crate::serde::de::Unexpected::Unsigned(value),
785                                        &"variant index"
786                                    ))
787                            }
788
789                            fn visit_str<E: $crate::serde::de::Error>(self, value: &str) -> Result<Self::Value, E> {
790                                match value {
791                                    $( stringify!($field) => Ok(Variants::$field), )*
792                                    _ => Err($crate::serde::de::Error::unknown_variant(value, VARIANTS)),
793                                }
794                            }
795                        }
796                        deserializer.deserialize_identifier(VariantsVisitor)
797                    }
798                }
799
800                struct EnumVisitor;
801                impl<'de> Visitor<'de> for EnumVisitor {
802                    type Value = $name;
803                    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
804                        formatter.write_str(concat!("enum ", stringify!($name)))
805                    }
806
807                    fn visit_enum<A: EnumAccess<'de>>(self, data: A) -> Result<Self::Value, A::Error> {
808                        match data.variant()? {
809                            $(
810                            (Variants::$field, variant) => {
811                                let () = variant.unit_variant()?;
812                                Ok($name::$field)
813                            }
814                            ),*
815                        }
816                    }
817                }
818                const VARIANTS: &'static [&'static str] = &[ $( stringify!( $field ) ),* ];
819                deserializer.deserialize_enum(
820                    stringify!($name),
821                    VARIANTS,
822                    EnumVisitor,
823                )
824            }
825        }
826    };
827}
828
829#[doc(hidden)]
831#[macro_export]
832macro_rules! enum_impl {
833    (FROMS $name: ident: [$($kind: ty),*]) => {
834        $(
835        impl From<$name> for $kind {
836            fn from(value: $name) -> Self {
837                Self::from(value as u8)
838            }
839        }
840        )*
841    };
842    (VALID_CORE $name: ident: [$($kind: ty),*]) => {
843        $(
844        unsafe impl $crate::ValidCheck<$kind> for $name {
845            const ALWAYS_VALID: bool = <Self as $crate::ValidCheck<u8>>::ALWAYS_VALID;
846            fn is_valid(value: $kind) -> bool {
847                Self::is_valid(value as u8)
848            }
849        }
850        )*
851    };
852    (COUNT $head:ident $(,$xs: ident)*) => {
853       1 + $crate::enum_impl!(COUNT $($xs),*)
854    };
855    (COUNT) => {
856        0
857    };
858    (VALID_BIT_STRUCT $name: ident: [$($kind: ty),*]) => {
859        $(
860        unsafe impl $crate::ValidCheck<$kind> for $name {
861            const ALWAYS_VALID: bool = <Self as $crate::ValidCheck<u8>>::ALWAYS_VALID;
862            fn is_valid(value: $kind) -> bool {
863                let inner = value.value();
864                Self::is_valid(inner as u8)
865            }
866        }
867        )*
868    };
869    (BITS_FIT_IN $name: ident: [$($kind: ty),+ $(,)?]) => {
870        $(
871        impl $crate::BitsFitIn<$kind> for $name {
872            fn fit(self) -> $kind {
873                (self as u8).fit()
874            }
875        }
876        )+
877    };
878    (FROM_IMPLS $name: ident) => {
879        $crate::enum_impl!(VALID_CORE $name: [u16, u32, u64, u128]);
880        $crate::enum_impl!(VALID_BIT_STRUCT $name: [$crate::u24, $crate::u40, $crate::u48, $crate::u56]);
881        $crate::enum_impl!(FROMS $name: [u8, u16, u32, u64, u128, $crate::u24, $crate::u40, $crate::u48, $crate::u56]);
882        $crate::enum_impl!(BITS_FIT_IN $name: [u8, u16, u32, u64, $crate::u24, $crate::u40, $crate::u48, $crate::u56]);
883
884        impl $crate::FieldStorage for $name {
885            type StoredType = u8;
886
887            fn inner_raw(self) -> Self::StoredType {
888                self as Self::StoredType
889            }
890        }
891
892    };
893    (
894        $(#[$meta:meta])*
895        $enum_vis: vis $name: ident($default: ident) {
896            $(#[$fst_field_meta:meta])*
897            $fst_field: ident
898            $(,
899                $(#[$field_meta:meta])*
900                $field: ident
901            )* $(,)?
902        }
903    ) => {
904        #[repr(u8)]
905        $(#[$meta])*
906        #[derive(Copy, Clone, Debug, PartialOrd, PartialEq, Eq)]
907        $enum_vis enum $name {
908            $(#[$fst_field_meta])*
909            $fst_field,
910            $(
911                $(#[$field_meta])*
912                $field
913            ),*
914        }
915
916        $crate::enum_serde_impl! { $name { $fst_field $(, $field)* } }
917
918        unsafe impl $crate::BitCount for $name {
919            const COUNT: usize = $crate::bits($crate::count_idents!(0, [$($field),*]));
920        }
921
922        impl $name {
923            const VARIANT_COUNT: usize = $crate::enum_impl!(COUNT $fst_field $(,$field)*);
924        }
925
926        unsafe impl $crate::ValidCheck<u8> for $name {
927            const ALWAYS_VALID: bool = Self::VARIANT_COUNT.count_ones() == 1;
928            fn is_valid(value: u8) -> bool {
929                if (value as usize) < Self::VARIANT_COUNT {
930                    true
931                } else {
932                    false
933                }
934            }
935        }
936
937        $crate::enum_impl!(FROM_IMPLS $name);
938
939        impl Default for $name {
940            fn default() -> Self {
941                Self::$default
942            }
943        }
944
945    };
946
947
948    (
949        $(#[$meta:meta])*
950        $enum_vis: vis $name: ident {
951            $(#[$fst_field_meta:meta])*
952            $fst_field: ident
953            $(,
954                $(#[$field_meta:meta])*
955                $field: ident
956            )* $(,)?
957        }
958    ) => {
959        #[repr(u8)]
960        $(#[$meta])*
961        #[derive(Copy, Clone, Debug, PartialOrd, PartialEq, Eq)]
962        $enum_vis enum $name {
963            $(#[$fst_field_meta])*
964            $fst_field,
965            $(
966                $(#[$field_meta])*
967                $field
968            ),*
969        }
970
971        $crate::enum_serde_impl! { $name { $fst_field $(, $field)* } }
972
973        impl Default for $name {
974            fn default() -> Self {
975                Self::$fst_field
976            }
977        }
978
979        impl $name {
980            const VARIANT_COUNT: usize = $crate::enum_impl!(COUNT $fst_field $(,$field)*);
981        }
982
983        unsafe impl $crate::BitCount for $name {
984            const COUNT: usize = $crate::bits($crate::count_idents!(0, [$($field),*]));
985        }
986
987
988        unsafe impl $crate::ValidCheck<u8> for $name {
989            const ALWAYS_VALID: bool = Self::VARIANT_COUNT.count_ones() == 1;
990
991            fn is_valid(value: u8) -> bool {
992                if (value as usize) < Self::VARIANT_COUNT {
993                    true
994                } else {
995                    false
996                }
997            }
998        }
999
1000        $crate::enum_impl!(FROM_IMPLS $name);
1001    };
1002}
1003
1004#[macro_export]
1033macro_rules! enums {
1034    (
1035        $(
1036        $(#[$meta:meta])*
1037        $enum_vis: vis $name: ident $(($enum_default: ident))? {
1038
1039            $(#[$fst_field_meta:meta])*
1040            $fst_field: ident
1041            $(,
1042                $(#[$field_meta:meta])*
1043                $field: ident
1044            )* $(,)?
1045        }
1046        )+
1047    ) => {
1048        $(
1049        $crate::enum_impl!(
1050        $(#[$meta])*
1051        $enum_vis $name $(($enum_default))? {
1052            $(#[$fst_field_meta])*
1053            $fst_field
1054            $(,
1055                $(#[$field_meta])*
1056                $field
1057            )*
1058        }
1059        );
1060        )+
1061    }
1062}
1063
1064#[macro_export]
1066macro_rules! create {
1067    (
1068        $struct_kind: ty {
1069            $($field: ident: $value: expr),* $(,)?
1070        }
1071    ) => {
1072        {
1073            let mut res = <$struct_kind>::of_defaults();
1074            $(
1075                res.$field().set($value);
1076            )*
1077            res
1078        }
1079    };
1080}