]> git.lizzy.rs Git - rust.git/blob - test.rs
bc7f5af826efad79dc780638b2bf2f4e2ab01724
[rust.git] / test.rs
1 #![allow(missing_docs)]
2
3 use embedded_hal::digital::v2::{InputPin, OutputPin};
4 use generic_array::{ArrayLength, GenericArray};
5 use heapless::Vec;
6
7 pub trait HeterogenousArray {
8     type Len;
9 }
10
11 /// Macro to implement a iterator on trait objects from a tuple struct.
12 #[macro_export]
13 macro_rules! impl_heterogenous_array {
14     ($s:ident, $t:ty, $len:tt, [$($idx:tt),+]) => {
15         impl<'a> IntoIterator for &'a $s {
16             type Item = &'a $t;
17             type IntoIter = generic_array::GenericArrayIter<&'a $t, $len>;
18             fn into_iter(self) -> Self::IntoIter {
19                 self.as_array().into_iter()
20             }
21         }
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()
27             }
28         }
29         impl $crate::matrix::HeterogenousArray for $s {
30             type Len = $len;
31         }
32         impl $s {
33             pub fn as_array(&self) -> generic_array::GenericArray<&$t, $len> {
34                 generic_array::arr![&$t; $( &self.$idx as &$t, )+]
35             }
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, )+]
38             }
39         }
40     }
41 }
42
43 pub struct Matrix<C, R> {
44     cols: C,
45     rows: R,
46 }
47
48 impl<C, R> Matrix<C, R> {
49     pub fn new<E>(cols: C, rows: R) -> Result<Self, E>
50         where
51                 for<'a> &'a mut R: IntoIterator<Item = &'a mut dyn OutputPin<Error = E>>,
52     {
53         let mut res = Self { cols, rows };
54         res.clear()?;
55         Ok(res)
56     }
57     pub fn clear<'a, E: 'a>(&'a mut self) -> Result<(), E>
58         where
59             &'a mut R: IntoIterator<Item = &'a mut dyn OutputPin<Error = E>>,
60     {
61         for r in self.rows.into_iter() {
62             r.set_high()?;
63         }
64         Ok(())
65     }
66     pub fn get<'a, E: 'a>(&'a mut self) -> Result<PressedKeys<R::Len, C::Len>, E>
67         where
68             &'a mut R: IntoIterator<Item = &'a mut dyn OutputPin<Error = E>>,
69             R: HeterogenousArray,
70             R::Len: ArrayLength<GenericArray<bool, C::Len>>,
71             &'a C: IntoIterator<Item = &'a dyn InputPin<Error = E>>,
72             C: HeterogenousArray,
73             C::Len: ArrayLength<bool>,
74     {
75         let cols = &self.cols;
76         self.rows
77             .into_iter()
78             .map(|r| {
79                 r.set_low()?;
80                 let col = cols
81                     .into_iter()
82                     .map(|c| c.is_low())
83                     .collect::<Result<Vec<_, C::Len>, E>>()?
84                     .into_iter()
85                     .collect();
86                 r.set_high()?;
87                 Ok(col)
88             })
89             .collect::<Result<Vec<_, R::Len>, E>>()
90             .map(|res| PressedKeys(res.into_iter().collect()))
91     }
92 }
93
94 #[derive(Default, PartialEq, Eq)]
95 pub struct PressedKeys<U, V>(pub GenericArray<GenericArray<bool, V>, U>)
96     where
97         V: ArrayLength<bool>,
98         U: ArrayLength<GenericArray<bool, V>>;
99
100 impl<U, V> PressedKeys<U, V>
101     where
102         V: ArrayLength<bool>,
103         U: ArrayLength<GenericArray<bool, V>>,
104 {
105     pub fn iter_pressed<'a>(&'a self) -> impl Iterator<Item = (usize, usize)> + Clone + 'a {
106         self.0.iter().enumerate().flat_map(|(i, r)| {
107             r.iter()
108                 .enumerate()
109                 .filter_map(move |(j, &b)| if b { Some((i, j)) } else { None })
110         })
111     }
112 }
113
114 impl<'a, U, V> IntoIterator for &'a PressedKeys<U, V>
115     where
116         V: ArrayLength<bool>,
117         U: ArrayLength<GenericArray<bool, V>>,
118         U: ArrayLength<&'a GenericArray<bool, V>>,
119 {
120     type IntoIter = core::slice::Iter<'a, GenericArray<bool, V>>;
121     type Item = &'a GenericArray<bool, V>;
122     fn into_iter(self) -> Self::IntoIter {
123         self.0.iter()
124     }
125 }