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+ }
0 commit comments