Rename AssociatedItems to AssocItems
Signed-off-by: Rustin-Liu <rustin.liu@gmail.com>
This commit is contained in:
parent
39eee173fb
commit
115e216067
1 changed files with 125 additions and 0 deletions
125
test.rs
Normal file
125
test.rs
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
#![allow(missing_docs)]
|
||||
|
||||
use embedded_hal::digital::v2::{InputPin, OutputPin};
|
||||
use generic_array::{ArrayLength, GenericArray};
|
||||
use heapless::Vec;
|
||||
|
||||
pub trait HeterogenousArray {
|
||||
type Len;
|
||||
}
|
||||
|
||||
/// Macro to implement a iterator on trait objects from a tuple struct.
|
||||
#[macro_export]
|
||||
macro_rules! impl_heterogenous_array {
|
||||
($s:ident, $t:ty, $len:tt, [$($idx:tt),+]) => {
|
||||
impl<'a> IntoIterator for &'a $s {
|
||||
type Item = &'a $t;
|
||||
type IntoIter = generic_array::GenericArrayIter<&'a $t, $len>;
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.as_array().into_iter()
|
||||
}
|
||||
}
|
||||
impl<'a> IntoIterator for &'a mut $s {
|
||||
type Item = &'a mut $t;
|
||||
type IntoIter = generic_array::GenericArrayIter<&'a mut $t, $len>;
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.as_mut_array().into_iter()
|
||||
}
|
||||
}
|
||||
impl $crate::matrix::HeterogenousArray for $s {
|
||||
type Len = $len;
|
||||
}
|
||||
impl $s {
|
||||
pub fn as_array(&self) -> generic_array::GenericArray<&$t, $len> {
|
||||
generic_array::arr![&$t; $( &self.$idx as &$t, )+]
|
||||
}
|
||||
pub fn as_mut_array(&mut self) -> generic_array::GenericArray<&mut $t, $len> {
|
||||
generic_array::arr![&mut $t; $( &mut self.$idx as &mut $t, )+]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Matrix<C, R> {
|
||||
cols: C,
|
||||
rows: R,
|
||||
}
|
||||
|
||||
impl<C, R> Matrix<C, R> {
|
||||
pub fn new<E>(cols: C, rows: R) -> Result<Self, E>
|
||||
where
|
||||
for<'a> &'a mut R: IntoIterator<Item = &'a mut dyn OutputPin<Error = E>>,
|
||||
{
|
||||
let mut res = Self { cols, rows };
|
||||
res.clear()?;
|
||||
Ok(res)
|
||||
}
|
||||
pub fn clear<'a, E: 'a>(&'a mut self) -> Result<(), E>
|
||||
where
|
||||
&'a mut R: IntoIterator<Item = &'a mut dyn OutputPin<Error = E>>,
|
||||
{
|
||||
for r in self.rows.into_iter() {
|
||||
r.set_high()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
pub fn get<'a, E: 'a>(&'a mut self) -> Result<PressedKeys<R::Len, C::Len>, E>
|
||||
where
|
||||
&'a mut R: IntoIterator<Item = &'a mut dyn OutputPin<Error = E>>,
|
||||
R: HeterogenousArray,
|
||||
R::Len: ArrayLength<GenericArray<bool, C::Len>>,
|
||||
&'a C: IntoIterator<Item = &'a dyn InputPin<Error = E>>,
|
||||
C: HeterogenousArray,
|
||||
C::Len: ArrayLength<bool>,
|
||||
{
|
||||
let cols = &self.cols;
|
||||
self.rows
|
||||
.into_iter()
|
||||
.map(|r| {
|
||||
r.set_low()?;
|
||||
let col = cols
|
||||
.into_iter()
|
||||
.map(|c| c.is_low())
|
||||
.collect::<Result<Vec<_, C::Len>, E>>()?
|
||||
.into_iter()
|
||||
.collect();
|
||||
r.set_high()?;
|
||||
Ok(col)
|
||||
})
|
||||
.collect::<Result<Vec<_, R::Len>, E>>()
|
||||
.map(|res| PressedKeys(res.into_iter().collect()))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, PartialEq, Eq)]
|
||||
pub struct PressedKeys<U, V>(pub GenericArray<GenericArray<bool, V>, U>)
|
||||
where
|
||||
V: ArrayLength<bool>,
|
||||
U: ArrayLength<GenericArray<bool, V>>;
|
||||
|
||||
impl<U, V> PressedKeys<U, V>
|
||||
where
|
||||
V: ArrayLength<bool>,
|
||||
U: ArrayLength<GenericArray<bool, V>>,
|
||||
{
|
||||
pub fn iter_pressed<'a>(&'a self) -> impl Iterator<Item = (usize, usize)> + Clone + 'a {
|
||||
self.0.iter().enumerate().flat_map(|(i, r)| {
|
||||
r.iter()
|
||||
.enumerate()
|
||||
.filter_map(move |(j, &b)| if b { Some((i, j)) } else { None })
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, U, V> IntoIterator for &'a PressedKeys<U, V>
|
||||
where
|
||||
V: ArrayLength<bool>,
|
||||
U: ArrayLength<GenericArray<bool, V>>,
|
||||
U: ArrayLength<&'a GenericArray<bool, V>>,
|
||||
{
|
||||
type IntoIter = core::slice::Iter<'a, GenericArray<bool, V>>;
|
||||
type Item = &'a GenericArray<bool, V>;
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.0.iter()
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue