bit_struct/
lib.rs

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/// Import serde here so we can reference it inside macros
15#[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/// [`UnsafeStorage`] is used to mark that there are some arbitrary invariants
32/// which must be maintained in storing its inner value. Therefore, creation and
33/// modifying of the inner value is an "unsafe" behavior. Although it might not
34/// be unsafe in traditional Rust terms (no memory unsafety), behavior might be
35/// "undefined"—or at least undocumented, because invariants are expected to be
36/// upheld.
37///
38/// This is useful in macros which do not encapsulate their storage in modules.
39/// This makes the macros for the end-user more ergonomic, as they can use the
40/// macro multiple times in a single module.
41#[repr(transparent)]
42#[derive(Copy, Clone, PartialOrd, PartialEq, Eq, Ord, Hash)]
43pub struct UnsafeStorage<T>(T);
44
45impl<T> UnsafeStorage<T> {
46    /// Create a new `UnsafeStorage` with the given inner value.
47    ///
48    /// # Safety
49    /// - See the broader scope that this is called in and which invariants are
50    ///   mentioned
51    pub const unsafe fn new_unsafe(inner: T) -> Self {
52        Self(inner)
53    }
54
55    /// Mutably access the value stored inside
56    ///
57    /// # Safety
58    /// This should be a safe operation assuming that when modifying T to T',
59    /// `UnsafeStorage::new_unsafe`(T') is safe
60    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    /// Access the value stored inside
67    fn as_ref(&self) -> &T {
68        &self.0
69    }
70}
71
72impl<T: Copy> UnsafeStorage<T> {
73    /// Access the value stored inside
74    pub const fn inner(&self) -> T {
75        self.0
76    }
77}
78
79/// A trait which defines how many bits are needed to store a struct.
80///
81/// # Safety
82/// Define `Num` as `{i,u}{8,16,32,64,128}`.
83/// - when calling `core::mem::transmute` on `Self`, only bits [0, COUNT) can be
84///   non-zero
85/// - `TryFrom<Num>` produces `Some(x)` <=> `core::mem::transmute(num)` produces
86///   a valid Self(x)
87/// - `TryFrom<Num>` produces `None` <=> `core::mem::transmute(num)` produces an
88///   invalid state for Self
89pub unsafe trait BitCount {
90    /// The number of bits associated with this type
91    const COUNT: usize;
92}
93
94/// A type which can be a field of a `bit_struct`
95pub trait FieldStorage {
96    /// The type this field stores as
97    type StoredType;
98    /// Get the raw representation of this value
99    fn inner_raw(self) -> Self::StoredType;
100}
101
102/// A conversion type for fitting the bits of one type into the bits of another
103/// type
104///
105/// This differs from [`Into`] because the value may not be semantically the
106/// same, this trait just asserts that the conversion can be done injectively.
107///
108/// The default implementation for our numeric types is to zero-extend the bits
109/// to fit the target size.
110pub trait BitsFitIn<T> {
111    /// Fits `self` into the target type
112    fn fit(self) -> T;
113}
114
115/// Check whether the underlying bits are valid
116///
117/// The type implementing this trait checks if the value stored in a bit
118/// representation of type `P` is a valid representation of this type. The
119/// [`enums`] macro implements this type for all of the integer-byte-width types
120/// from this crate.
121///
122/// # Safety
123///
124/// The [`ValidCheck::is_valid`] function must be correctly implemented or else
125/// other functions in this crate won't work correctly. Implementation of this
126/// trait is preferably done by public macros in this crate, which will
127/// implement it correctly.
128pub unsafe trait ValidCheck<P> {
129    /// Set this to true if, at compile-time, we can tell that all bit
130    /// representations which contain the appropriate number of bits are valid
131    /// representations of this type
132    const ALWAYS_VALID: bool = false;
133    /// Return whether or not the underlying bits of `P` are valid
134    /// representation of this type
135    fn is_valid(_input: P) -> bool {
136        true
137    }
138}
139
140/// A struct which allows for getting/setting a given property
141pub struct GetSet<'a, P, T, const START: usize, const STOP: usize> {
142    /// The referenced bitfield type.
143    parent: &'a mut P,
144    /// The type in the get/set operations
145    _phantom: PhantomData<&'a mut T>,
146}
147
148impl<'a, P, T, const START: usize, const STOP: usize> GetSet<'a, P, T, START, STOP> {
149    /// The bit offset at which this `GetSet` instance starts
150    pub const fn start(&self) -> usize {
151        START
152    }
153
154    /// The bit offset at which this `GetSet` instance ends
155    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    /// Create a new [`GetSet`]. This should be called from methods generated by
169    /// the [`bit_struct`] macro
170    pub fn new(parent: &'a mut P) -> Self {
171        Self {
172            parent,
173            _phantom: PhantomData::default(),
174        }
175    }
176
177    /// Get a mask of `STOP-START + 1` length. This doesn't use the shift left
178    /// and subtract one trick because of the special case where `(0b1 <<
179    /// (STOP - START + 1)) - 1` will cause an overflow
180    // Because `GetSet` has a lot of type parameters, it's easiest to be able to invoke this method
181    // directly on a value instead of having to match the type parameters.
182    #[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    /// Get the property this `GetSet` points at
210    pub fn get(&self) -> T {
211        let section = self.get_raw();
212        // Safety:
213        // This is guaranteed to be safe because the underlying storage must be bigger
214        // than any fields stored within
215        unsafe { core::mem::transmute_copy(&section) }
216    }
217
218    /// Returns true if the memory this `GetSet` points at is a valid
219    /// representation of `T`
220    pub fn is_valid(&self) -> bool {
221        let section = self.get_raw();
222        T::is_valid(section)
223    }
224
225    /// Get the raw bits being pointed at, without type conversion nor any form
226    /// of validation
227    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    /// Set the property in the slice being pointed to by this `GetSet`
251    pub fn set(&mut self, value: T) {
252        // SAFETY:
253        // This is safe because we produce it from a valid value of `T`, so we meet the
254        // safety condition on `set_raw`
255        unsafe { self.set_raw(value.fit()) }
256    }
257
258    /// Set the field to a raw value.
259    /// # Safety
260    /// value must be a valid representation of the field. i.e.,
261    /// `core::mem::transmute` between P and T must be defined.
262    pub unsafe fn set_raw(&mut self, value: P) {
263        let mask = self.mask();
264        let mask_shifted = mask << START;
265
266        // zero out parent
267        *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
275/// A trait that all bit structs implement
276///
277/// See the [`bit_struct`] macro for more details.
278pub trait BitStruct<const ALWAYS_VALID: bool> {
279    /// The underlying type used to store the bit struct
280    type Kind;
281    /// Produce a bit struct from the given underlying storage, without checking
282    /// for validity.
283    ///
284    /// # Safety
285    ///
286    /// The caller is responsible for verifying that this value is a valid value
287    /// for the bit struct.
288    ///
289    /// If this is guaranteed to be safe (i.e. all possibly inputs for `value`
290    /// are valid), then the bit struct will also implement [`BitStructExt`]
291    /// which has the [`BitStructExt::exact_from`] method, that you should
292    /// use instead.
293    unsafe fn from_unchecked(value: Self::Kind) -> Self;
294}
295
296/// An extension trait for bit structs which can be safely made from any value
297/// in their underlying storage type.
298pub trait BitStructExt: BitStruct<true> {
299    /// Produce a bit struct from the given underlying storage
300    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        // SAFETY:
306        // This is safe because this method only exists for bitfields for which it is
307        // always safe to call `from_unchecked`
308        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/// Helper macro
327#[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            /// Creates an empty struct. This may or may not be valid
343            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            /// the defaults
349            ///
350            /// This is different than [`Self::default()`], because the actual default implementation
351            /// might not be composed of only the defaults of the given fields.
352            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/// `serde` feature is not provided, so don't implement it
375#[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/// `serde` feature is provided, so implement it
386#[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
495/// A bit struct which has a zero value we can get
496pub trait BitStructZero: Zero {
497    /// Get a zero value for this bit struct
498    fn bs_zero() -> Self {
499        Self::zero()
500    }
501}
502
503impl<T: Zero> BitStructZero for T {}
504
505// the main is actually needed
506
507#[allow(clippy::needless_doctest_main)]
508/// Create a bit struct.
509///
510///
511/// This macro can only be used once for each module.
512/// This is because the macro creates sub-module to limit access to certain
513/// unsafe access. In the macro, bit-structs can be defined just like a struct
514/// outside of the the macro. The catch is a **base type** must be specified.
515/// Valid base types are u{8,16,32,64,128}. The elements stored in the struct
516/// are statically guaranteed to not exceed the number of bits in the base type.
517/// This means we cannot store a `u16` in a `u8`, but it also means we cannot
518/// store 9 `u1`s in a u8.
519///
520/// Elements start at the top of the number (for a u16 this would be the 15th
521/// bit) and progress down.
522///
523/// # Example
524/// ```
525/// bit_struct::enums! {
526///     /// The default value for each enum is always the first
527///     pub ThreeVariants { Zero, One, Two }
528///
529///     /// This is syntax to set the default value to Cat
530///     pub Animal(Cat) { Cow, Bird, Cat, Dog }
531///
532///     pub Color { Orange, Red, Blue, Yellow, Green }
533/// }
534///
535/// bit_struct::bit_struct! {
536///     /// We can write documentation for the struct here.
537///     struct BitStruct1 (u16){
538///         /// a 1 bit element. This is stored in u16[15]
539///         a: bit_struct::u1,
540///
541///         /// This is calculated to take up 2 bits. This is stored in u16[13..=14]
542///         variant: ThreeVariants,
543///
544///         /// This also takes 2 bits. This is stored in u16[11..=12]
545///         animal: Animal,
546///
547///         /// This takes up 3 bits. This is stored u16[8..=10]
548///         color: Color,
549///     }
550///
551///     struct BitStruct2(u32) {
552///         /// We could implement for this too. Note, this does not have a default
553///         a_color: Color,
554///         b: bit_struct::u3,
555///     }
556/// }
557///
558/// fn main() {
559///     use std::convert::TryFrom;
560///     let mut bit_struct: BitStruct1 = BitStruct1::of_defaults();
561///
562///     assert_eq!(bit_struct.a().start(), 15);
563///     assert_eq!(bit_struct.a().stop(), 15);
564///
565///     assert_eq!(bit_struct.color().start(), 8);
566///     assert_eq!(bit_struct.color().stop(), 10);
567///
568///     assert_eq!(
569///         format!("{:?}", bit_struct),
570///         "BitStruct1 { a: 0, variant: Zero, animal: Cat, color: Orange }"
571///     );
572///     assert_eq!(bit_struct.raw(), 4096);
573///
574///     let reverse_bit_struct = BitStruct1::try_from(4096);
575///     assert_eq!(
576///         format!("{:?}", reverse_bit_struct),
577///         "Ok(BitStruct1 { a: 0, variant: Zero, animal: Cat, color: Orange })"
578///     );
579///
580///     // u3! macro provides a static assert that the number is not too large
581///     let mut other_struct = BitStruct2::new(Color::Green, bit_struct::u3!(0b101));
582///     assert_eq!(
583///         format!("{:?}", other_struct),
584///         "BitStruct2 { a_color: Green, b: 5 }"
585///     );
586///
587///     assert_eq!(other_struct.a_color().get(), Color::Green);
588///
589///     other_struct.a_color().set(Color::Red);
590///
591///     assert_eq!(other_struct.a_color().get(), Color::Red);
592/// }
593/// ```
594#[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
696/// Returns the index of the leading 1 in `num`
697///
698/// Example:
699/// ```
700/// # use bit_struct::bits;
701///
702/// assert_eq!(bits(2), 2);
703/// assert_eq!(bits(3), 2);
704/// assert_eq!(bits(5), 3);
705/// assert_eq!(bits(32), 6);
706/// ```
707pub const fn bits(num: usize) -> usize {
708    /// Helper function for [`bits`]
709    const fn helper(count: usize, on: usize) -> usize {
710        // 0b11 = 3  log2_ceil(0b11) = 2 .. 2^2
711        // 0b10 = 2 log2_ceil = 2 .. 2^1
712        if on > 0 {
713            helper(count + 1, on >> 1)
714        } else {
715            count
716        }
717    }
718
719    helper(0, num)
720}
721
722/// `serde` feature is not provided, so don't implement it
723#[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/// `serde` feature is provided, so implement it
731#[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                            // SAFETY:
764                            // This is safe because we're converting a `u64` to a `repr(u64)`
765                            // enum, and we've checked that the value is one of the variants.
766                            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/// Helper macro
830#[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/// Create enums with trait implementations necessary for use in a `bit_struct`
1005/// field.
1006///
1007/// Example:
1008/// ```
1009/// # use bit_struct::enums;
1010///
1011/// enums! {
1012///     pub Colors { Red, Green, Blue }
1013///
1014///     Shapes { Triangle, Circle, Square }
1015/// }
1016/// ```
1017///
1018/// By default, this macro produces an impl of [`Default`] in which the first
1019/// field listed is made the default. However, you can also specify some other
1020/// variant as the default, as follows:
1021/// ```
1022/// # use bit_struct::enums;
1023///
1024/// enums! {
1025///     DefaultsToA { A, B, C }
1026///     DefaultsToB (B) { A, B, C }
1027/// }
1028///
1029/// assert_eq!(DefaultsToA::default(), DefaultsToA::A);
1030/// assert_eq!(DefaultsToB::default(), DefaultsToB::B);
1031/// ```
1032#[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/// Create a `bit_struct`
1065#[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}