Macro layout

Source
macro_rules! layout {
    (item = DualView; [] -> [$($output:tt)*]) => { ... };
    (item = DualView; [$m:literal $d:literal, $($input:tt)*] -> [$($output:tt)*]) => { ... };
    (item = DualView; [$m:literal, $($input:tt)*] -> [$($output:tt)*]) => { ... };
    (DualView; $(#[$meta:meta])* $vis:vis $ident:ident $name:ident($value:tt); $($input:tt)*) => { ... };
    (item = FlagType; array = $a:expr; index = $i:expr;) => { ... };
    (item = FlagType; array = $a:expr; index = $i:expr; Undefined, $($input:tt)*) => { ... };
    (item = FlagType; array = $a:expr; index = $i:expr; Unknown, $($input:tt)*) => { ... };
    (item = FlagType; array = $a:expr; index = $i:expr; ShouldBe1, $($input:tt)*) => { ... };
    (item = FlagType; array = $a:expr; index = $i:expr; ShouldBe0, $($input:tt)*) => { ... };
    (item = FlagType; array = $a:expr; index = $i:expr; $m:literal: $n:expr, $($input:tt)*) => { ... };
    (item = FlagType; array = $a:expr; index = $i:expr; $m:literal $d:literal, $($input:tt)*) => { ... };
    (item = FlagType; array = $a:expr; index = $i:expr; $m:literal, $($input:tt)*) => { ... };
    (FlagType; $(#[$meta:meta])* $vis:vis $ident:ident $name:ident($value:tt); $($input:tt)*) => { ... };
    (@as_expr $expr:expr) => { ... };
    (@as_ty $ty:ty) => { ... };
    (@count_bytes u8) => { ... };
    (@count_bytes u16) => { ... };
    (@count_bytes u32) => { ... };
    (@count_bytes u64) => { ... };
    (@count_bytes u128) => { ... };
    (@count_bytes [u8; $n:expr]) => { ... };
}
Expand description

Fast defining of useful types

This macro helps to implement crate::BitFieldLayout trait and create associated const layout. Macro may be used for following data types:

§DualView


// Data created by macro
let macro_data = {
    layout!(
        DualView;
        struct Letters(u8);
        "a",
        "b" "B",
        "c",
        "d",
        "e",
        "f" "F",
        "g" "G",
        "h" "H",
    );

    Letters(42).flags()
};
// Expands to:
let manual_data = {
    struct Letters(u8);
    impl Letters {
        const LAYOUT: [DualView<'static>; 8] = [
            DualView("a", "a"),
            DualView("b", "B"),
            DualView("c", "c"),
            DualView("d", "d"),
            DualView("e", "e"),
            DualView("f", "F"),
            DualView("g", "G"),
            DualView("h", "H"),
        ];
    }
     
    impl Layout for Letters {
        type Layout = slice::Iter<'static, DualView<'static>>;
        fn layout() -> Self::Layout { Letters::LAYOUT.iter() }
    }
    impl BitFieldLayout for Letters {
        type Value = u8;
        fn get(&self) -> Self::Value { self.0 }
        fn set(&mut self, new: Self::Value) { self.0 = new; }
    }

    Letters(42).flags()
};

assert_eq!(macro_data.collect::<Vec<_>>(), manual_data.collect::<Vec<_>>());

§FlagType

let macro_data = {
    layout!(
        FlagType;
        struct EightFlags(u8);
        "Significant: meaning",
        "Significant: meaning" "Significant: description",
        "Reserved: 2 bits": 2,
        "Reserved: shouldn't exists": 0,
        ShouldBe0,
        ShouldBe1,
        Unknown,
        Undefined,
    );

    EightFlags(73).flags()
};
// Expands to:
let manual_data = {
    struct EightFlags(u8);
    impl EightFlags {
        const LAYOUT: [FlagType<'static>; 8] = [
            FlagType::Significant("Significant: meaning", "Significant: meaning"),
            FlagType::Significant("Significant: meaning", "Significant: description"),
            FlagType::Reserved("Reserved: 2 bits"),
            FlagType::Reserved("Reserved: 2 bits"),
            FlagType::ShouldBe0,
            FlagType::ShouldBe1,
            FlagType::Unknown,
            FlagType::Undefined,
        ];
    }
     
    impl Layout for EightFlags {
        type Layout = slice::Iter<'static, FlagType<'static>>;
        fn layout() -> Self::Layout { EightFlags::LAYOUT.iter() }
    }
    impl BitFieldLayout for EightFlags {
        type Value = u8;
        fn get(&self) -> Self::Value { self.0 }
        fn set(&mut self, new: Self::Value) { self.0 = new; }
    }

    EightFlags(73).flags()
};

assert_eq!(macro_data.collect::<Vec<_>>(), manual_data.collect::<Vec<_>>());