1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/// Create a config for [`DebouncedInput`](crate::DebouncedInput).
///
/// # Example 1
/// ```ignore
/// debounced_input_config!(
///     SomeDebouncedInputConfig,
///     debounce_timer: MyElapsedTimer = MyElapsedTimer::new(20.millis())
/// );
///
/// type MyDebouncedInput<InputSwitch> = DebouncedInput<InputSwitch, SomeDebouncedInputConfig>;
/// ```
///
/// # Example 2
/// ```ignore
/// debounced_input_config!(
///     pub SomeDebouncedInputConfig,
///     debounce_timer: MyElapsedTimer = MyElapsedTimer::new(20.millis())
/// );
///
/// type MyDebouncedInput<InputSwitch> = DebouncedInput<InputSwitch, SomeDebouncedInputConfig>;
/// ```
///
/// # Example 3
/// ```ignore
/// pub struct SomeDebouncedInputConfig;
///
/// debounced_input_config!(
///     impl SomeDebouncedInputConfig,
///     debounce_timer: MyElapsedTimer = MyElapsedTimer::new(20.millis())
/// );
///
/// type MyDebouncedInput<InputSwitch> = DebouncedInput<InputSwitch, SomeDebouncedInputConfig>;
/// ```
#[macro_export]
macro_rules! debounced_input_config {
    (impl $config_name:ty, debounce_timer: $timer_type:ty = $timer_value:expr) => {
        impl embedded_controls::DebouncedInputConfig for $config_name {
            type Timer = $timer_type;
            const DEBOUNCE_TIMER: $timer_type = $timer_value;
        }
    };
    ($vis:vis $config_name:ident, debounce_timer: $timer_type:ty = $timer_value:expr) => {
        $vis struct $config_name;

        debounced_input_config!(
            impl $config_name,
            debounce_timer: $timer_type = $timer_value
        );
    };
}

/// Create a config for [`Encoder`](crate::Encoder).
///
/// # Example 1
/// ```ignore
/// encoder_config!(
///     SomeEncoderConfig,
///     debounce_timer: MyElapsedTimer = MyElapsedTimer::new(2.millis()),
///     counts_div: i8 = 4
/// );
///
/// type MyEncoder<SwitchA, SwitchB> = Encoder<SwitchA, SwitchB, SomeEncoderConfig>;
/// ```
///
/// # Example 2
/// ```ignore
/// encoder_config!(
///     pub SomeEncoderConfig,
///     debounce_timer: MyElapsedTimer = MyElapsedTimer::new(2.millis()),
///     counts_div: i8 = 4
/// );
///
/// type MyEncoder<SwitchA, SwitchB> = Encoder<SwitchA, SwitchB, SomeEncoderConfig>;
/// ```
///
/// # Example 3
/// ```ignore
/// pub struct SomeEncoderConfig;
///
/// encoder_config!(
///     impl SomeEncoderConfig,
///     debounce_timer: MyElapsedTimer = MyElapsedTimer::new(2.millis()),
///     counts_div: i8 = 4
/// );
///
/// type MyEncoder<SwitchA, SwitchB> = Encoder<SwitchA, SwitchB, SomeEncoderConfig>;
/// ```
#[macro_export]
macro_rules! encoder_config {
    (
        impl $config_name:ty,
        debounce_timer: $timer_type:ty = $timer_value:expr,
        counts_div: $counts_type:ty = $counts_div_value:expr
    ) => {
        embedded_controls::debounced_input_config!(
            impl $config_name,
            debounce_timer: $timer_type = $timer_value
        );

        impl embedded_controls::EncoderConfig for $config_name {
            type Counts = $counts_type;
            const COUNTS_DIV: $counts_type = $counts_div_value;
        }
    };
    (
        $vis:vis $config_name:ident,
        debounce_timer: $timer_type:ty = $timer_value:expr,
        counts_div: $counts_type:ty = $counts_div_value:expr
    ) => {
        $vis struct $config_name;

        encoder_config!(impl $config_name,
            debounce_timer: $timer_type = $timer_value,
            counts_div: $counts_type = $counts_div_value
        );
    };
}