diff options
| author | Rustin-Liu <rustin.liu@gmail.com> | 2020-04-24 22:05:32 +0800 |
|---|---|---|
| committer | hi-rustin <rustin.liu@gmail.com> | 2021-04-05 22:57:14 +0800 |
| commit | 115e216067aff0b7b2fa55d9a66394f14a3a8397 (patch) | |
| tree | a8f76545b1f08022a8617f83de489807a2981b1b | |
| parent | 39eee173fbcc21462d255b364b87715cd33b62db (diff) | |
| download | rust-115e216067aff0b7b2fa55d9a66394f14a3a8397.tar.gz rust-115e216067aff0b7b2fa55d9a66394f14a3a8397.zip | |
Rename AssociatedItems to AssocItems
Signed-off-by: Rustin-Liu <rustin.liu@gmail.com>
| -rw-r--r-- | test.rs | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/test.rs b/test.rs new file mode 100644 index 00000000000..bc7f5af826e --- /dev/null +++ b/test.rs @@ -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() + } +} \ No newline at end of file |
