1 #![allow(missing_docs)]
3 use embedded_hal::digital::v2::{InputPin, OutputPin};
4 use generic_array::{ArrayLength, GenericArray};
7 pub trait HeterogenousArray {
11 /// Macro to implement a iterator on trait objects from a tuple struct.
13 macro_rules! impl_heterogenous_array {
14 ($s:ident, $t:ty, $len:tt, [$($idx:tt),+]) => {
15 impl<'a> IntoIterator for &'a $s {
17 type IntoIter = generic_array::GenericArrayIter<&'a $t, $len>;
18 fn into_iter(self) -> Self::IntoIter {
19 self.as_array().into_iter()
22 impl<'a> IntoIterator for &'a mut $s {
23 type Item = &'a mut $t;
24 type IntoIter = generic_array::GenericArrayIter<&'a mut $t, $len>;
25 fn into_iter(self) -> Self::IntoIter {
26 self.as_mut_array().into_iter()
29 impl $crate::matrix::HeterogenousArray for $s {
33 pub fn as_array(&self) -> generic_array::GenericArray<&$t, $len> {
34 generic_array::arr![&$t; $( &self.$idx as &$t, )+]
36 pub fn as_mut_array(&mut self) -> generic_array::GenericArray<&mut $t, $len> {
37 generic_array::arr![&mut $t; $( &mut self.$idx as &mut $t, )+]
43 pub struct Matrix<C, R> {
48 impl<C, R> Matrix<C, R> {
49 pub fn new<E>(cols: C, rows: R) -> Result<Self, E>
51 for<'a> &'a mut R: IntoIterator<Item = &'a mut dyn OutputPin<Error = E>>,
53 let mut res = Self { cols, rows };
57 pub fn clear<'a, E: 'a>(&'a mut self) -> Result<(), E>
59 &'a mut R: IntoIterator<Item = &'a mut dyn OutputPin<Error = E>>,
61 for r in self.rows.into_iter() {
66 pub fn get<'a, E: 'a>(&'a mut self) -> Result<PressedKeys<R::Len, C::Len>, E>
68 &'a mut R: IntoIterator<Item = &'a mut dyn OutputPin<Error = E>>,
70 R::Len: ArrayLength<GenericArray<bool, C::Len>>,
71 &'a C: IntoIterator<Item = &'a dyn InputPin<Error = E>>,
73 C::Len: ArrayLength<bool>,
75 let cols = &self.cols;
83 .collect::<Result<Vec<_, C::Len>, E>>()?
89 .collect::<Result<Vec<_, R::Len>, E>>()
90 .map(|res| PressedKeys(res.into_iter().collect()))
94 #[derive(Default, PartialEq, Eq)]
95 pub struct PressedKeys<U, V>(pub GenericArray<GenericArray<bool, V>, U>)
98 U: ArrayLength<GenericArray<bool, V>>;
100 impl<U, V> PressedKeys<U, V>
102 V: ArrayLength<bool>,
103 U: ArrayLength<GenericArray<bool, V>>,
105 pub fn iter_pressed<'a>(&'a self) -> impl Iterator<Item = (usize, usize)> + Clone + 'a {
106 self.0.iter().enumerate().flat_map(|(i, r)| {
109 .filter_map(move |(j, &b)| if b { Some((i, j)) } else { None })
114 impl<'a, U, V> IntoIterator for &'a PressedKeys<U, V>
116 V: ArrayLength<bool>,
117 U: ArrayLength<GenericArray<bool, V>>,
118 U: ArrayLength<&'a GenericArray<bool, V>>,
120 type IntoIter = core::slice::Iter<'a, GenericArray<bool, V>>;
121 type Item = &'a GenericArray<bool, V>;
122 fn into_iter(self) -> Self::IntoIter {