macro_rules! bitfield {
    (
        $(#[$doc:meta])*
        $access:vis u8 $name:ident
        $(
            $(#[$flag_doc:meta])*
            $flag:ident {
                $(
                    $(#[$member_doc:meta])*
                    $idx:literal : $field:ident $( : ( $named_getter:ident ) )?,
                )*
            }
        )?
    ) => { ... };
    (
        $(#[$doc:meta])*
        $access:vis u16 $name:ident
        $(
            $(#[$flag_doc:meta])*
            $flag:ident {
                $(
                    $(#[$member_doc:meta])*
                    $idx:literal : $field:ident $( ( $named_getter:ident ) )?,
                )*
            }
        )?
    ) => { ... };
    (
        $(#[$doc:meta])*
        $access:vis u32 $name:ident
        $(
            $(#[$flag_doc:meta])*
            $flag:ident {
                $(
                    $(#[$member_doc:meta])*
                    $idx:literal : $field:ident $( ( $named_getter:ident ) )?,
                )*
            }
        )?
    ) => { ... };
    (
        $(#[$doc:meta])*
        $access:vis u64 $name:ident
        $(
            $(#[$flag_doc:meta])*
            $flag:ident {
                $(
                    $(#[$member_doc:meta])*
                    $idx:literal : $field:ident $( ( $named_getter:ident ) )?,
                )*
            }
        )?
    ) => { ... };
    (
        $(#[$doc:meta])*
        $access:vis u128 $name:ident
        $(
            $(#[$flag_doc:meta])*
            $flag:ident {
                $(
                    $(#[$member_doc:meta])*
                    $idx:literal : $field:ident $( ( $named_getter:ident ) )?,
                )*
            }
        )?
    ) => { ... };
    (
        $(#[$doc:meta])*
        $access:vis usize $name:ident
        $(
            $(#[$flag_doc:meta])*
            $flag:ident {
                $(
                    $(#[$member_doc:meta])*
                    $idx:literal : $field:ident $( ( $named_getter:ident ) )?,
                )*
            }
        )?
    ) => { ... };
}
Expand description

Generates a bitfield struct and a corresponding flag enum.

Can be used multiple times in a single codebase as long as the identifiers are unique or are isolated so as not to clash.

See the examples module for examples of the generated output.

Args

  • pub - optional accessor: if provided, both generated items will public. If omitted, both will be private.
    see here for possible visibility options.

  • ExampleField - name for the generated bitfield struct. (results in struct ExampleField(...))

  • ExampleFlags - name for the generated flag enum. (results in enum ExampleFlags { ... })

  • u8 - unsigned integer type to use as a bit array. Must be an unsigned integer
    valid options are: u8,u16, u32, u64, u128, usize

  • 0 : Flag0 - defines each member of the flag enum.
    The left hand side must be a u8 (0..=254) and must be less than the number of bits in the underlying unsigned type. This value determines the index of the target bit within the field.
    The right hand side can be any valid identifier (unique to this enum). These identifiers will be used to access the corresponding field.

  • /// docstrings - Each element can take optional docstrings. This includes the bit field struct, the flag enum, and each member within the flag enum. See examples for more information.

Examples:

Full Example - (see below for explanation for each parameter):

use ubits::bitfield;

    bitfield! {
        /// Optional docstring
        /// for [`ExampleField`] struct
        pub u8 ExampleField
        /// Optional docstring
        /// for [`ExampleFlags`] enum
        ExampleFlags {
            /// Optional docstring for [`ExampleFlags::Flag0`]
            0 : Flag0,
            /// Optional docstring for [`ExampleFlags::Flag1`]
            1 : Flag1,
            /// Optional docstring for [`ExampleFlags::Flag2`]
            2 : Flag2,
            /// Optional docstring for [`ExampleFlags::Flag3`]
            3 : Flag3,
            /// Optional docstring for [`ExampleFlags::Flag4`]
            4 : Flag4,
            /// Optional docstring for [`ExampleFlags::Flag5`]
            5 : Flag5,
            /// Optional docstring for [`ExampleFlags::Flag6`]
            6 : Flag6,
            /// Optional docstring for [`ExampleFlags::Flag7`]
            7 : Flag7,
        }
    }

You don’t have to name all the fields if you don’t need them…

You can use just a few from the front:

use ubits::bitfield;

    bitfield! {
        /// Optional docstring
        /// for [`ExampleField`] struct
        pub u8 ExampleField
        /// Optional docstring
        /// for [`ExampleFlags`] enum
        ExampleFlags {
            /// Optional docstring for [`ExampleFlags::Flag0`]
            0 : Flag0,
            /// Optional docstring for [`ExampleFlags::Flag1`]
            1 : Flag1,
            /// Optional docstring for [`ExampleFlags::Flag2`]
            2 : Flag2,
        }
    }

… or any valid indices:

use ubits::bitfield;

    bitfield! {
        /// Optional docstring
        /// for [`ExampleField`] struct
        pub u8 ExampleField
        /// Optional docstring
        /// for [`ExampleFlags`] enum
        ExampleFlags {
            /// Optional docstring for [`ExampleFlags::Flag0`]
            0 : Flag0,
            /// Optional docstring for [`ExampleFlags::Flag1`]
            3 : Flag1,
            /// Optional docstring for [`ExampleFlags::Flag2`]
            6 : Flag2,
        }
    }

… or just omit the flags altogether and use indices only.:

use ubits::bitfield;
    bitfield! {
        /// Optional docstring
        /// for [`ExampleField`] struct
        pub u8 ExampleField
    }

Note: if you omit flags, no flag enum will be generated and no methods for the bitfield struct that rely on flags will be generated.