macro_rules! keypad_struct {
    (
        $(#[$attributes:meta])* $visibility:vis struct $struct_name:ident {
            rows: ( $($row_type:ty),* $(,)* ),
            columns: ( $($col_type:ty),* $(,)* ),
        }
    ) => { ... };
    (
        $(#[$attributes:meta])* $visibility:vis struct $struct_name:ident <Error = $error_type:ty> {
            rows: ( $($row_type:ty),* $(,)* ),
            columns: ( $($col_type:ty),* $(,)* ),
        }
    ) => { ... };
    (@array2d_type $element_type:ty, ($($row:ty),*) ($($col:ty),*) ) => { ... };
    (@array1d_type $element_type:ty, ($($col:ty),*)) => { ... };
    (@count $($token_trees:tt)*) => { ... };
    (@replace $_t:tt $sub:expr) => { ... };
    (@underscore $unused:tt) => { ... };
    (@destructure_ref $tuple:expr, ($($repeat_n:ty),*)) => { ... };
    (@tuple_helper $tuple:expr, ($head:ty), ($($result:expr),*  $(,)*)) => { ... };
    (@tuple_helper $tuple:expr, ($head:ty $(,$repeats:ty)* $(,)*),  ($($result:expr),*  $(,)*)) => { ... };
    (@tuple $tuple:expr, ($($repeats:ty),*)) => { ... };
}
Expand description

Define a new struct representing your keypad matrix circuit.

Every pin has a unique type, depending on its pin number and its current mode. This struct is where you specify which pin types will be used in the rows and columns of the keypad matrix. All the row pins must implement the InputPin trait, and the column pins must implement the OutputPin trait. The associated Error type of the InputPin and OutputPin traits must be the same for every row and column pin, and you must specify it after your struct name with <Error = ...>

You can specify the visibility of the struct (eg. pub) as usual, and add doc comments using the #[doc="..."] attribute.

Don’t access or modify the struct’s fields directly. Instead, use the methods implemented by this macro, documented here: example_generated::ExampleKeypad

Example

#[macro_use]
extern crate keypad;

use keypad::mock_hal::{self, Input, OpenDrain, Output, PullUp};
use core::convert::Infallible;

keypad_struct! {
    #[doc="My super-special keypad."]
    pub struct ExampleKeypad<Error = Infallible> {
        rows: (
            mock_hal::gpioa::PA0<Input<PullUp>>,
            mock_hal::gpioa::PA1<Input<PullUp>>,
            mock_hal::gpioa::PA2<Input<PullUp>>,
            mock_hal::gpioa::PA3<Input<PullUp>>,
        ),
        columns: (
            mock_hal::gpioa::PA4<Output<OpenDrain>>,
            mock_hal::gpioa::PA5<Output<OpenDrain>>,
            mock_hal::gpioa::PA6<Output<OpenDrain>>,
            mock_hal::gpioa::PA7<Output<OpenDrain>>,
            mock_hal::gpioa::PA8<Output<OpenDrain>>,
        ),
    }
}

Safety

This macro uses unsafe to create an array with uninitialized memory, which is then immediately initialized in a loop. This is fine as long as there is not a bug in how the macro calculates the dimensions of the array.