#[rustfmt::ignore]
use alloc::vec;
use alloc::vec::Vec;
use crate::matrix::Scan;
#[derive(Copy, Clone, Debug)]
pub enum DebounceState {
Steady(bool),
Bouncing {
last_steady: bool,
last_read: bool,
ctr: usize,
},
}
pub trait State<S: Scan> {
fn init() -> Self;
fn get_state(&self, x: usize, y: usize) -> DebounceState;
fn set_state(&mut self, x: usize, y: usize, state: DebounceState);
}
impl<S: Scan> State<S> for Vec<Vec<DebounceState>> {
#[inline]
fn init() -> Self {
vec![vec![DebounceState::Steady(false); S::NREAD as _]; S::NPULL as _]
}
#[inline]
fn get_state(&self, x: usize, y: usize) -> DebounceState {
self[x][y]
}
#[inline]
fn set_state(&mut self, x: usize, y: usize, state: DebounceState) {
self[x][y] = state;
}
}
macro_rules! impl_state {
(@common $x:expr, $y:expr) => {
impl<Sc: Scan> State<Sc> for [[DebounceState; $y]; $x] {
#[inline]
fn init() -> Self {
if Sc::NPULL != $x || Sc::NREAD != $y {
panic!("Invalid state dimensions, need {}:{} for scanner, got {}:{}", Sc::NPULL, Sc::NREAD, $x, $y);
}
[[DebounceState::Steady(false); $y]; $x]
}
#[inline]
fn get_state(&self, x: usize, y: usize) -> DebounceState {
self[x ][y ]
}
#[inline]
fn set_state(&mut self, x: usize, y: usize, state: DebounceState) {
self[x ][y ] = state;
}
}
};
(@y $x:expr ; [$($y:expr),*]) => {
$(
impl_state!(@common $x, $y);
)*
};
(@both [$($x:expr),*] ; $y:tt) => {
$(
impl_state!(@y $x; $y);
)*
};
($($n:expr),*) => {
impl_state!(@both [$($n),*]; [$($n),*]);
};
}
#[cfg(not(feature = "exhaustive"))]
const _DUMMY: () = {
impl_state!(@common 4, 6);
impl_state!(@common 4, 12);
impl_state!(@common 5, 7);
impl_state!(@common 5, 14);
};
#[cfg(feature = "exhaustive")]
impl_state!(
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
);