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