]> git.lizzy.rs Git - rust.git/commitdiff
Rename AssociatedItems to AssocItems
authorRustin-Liu <rustin.liu@gmail.com>
Fri, 24 Apr 2020 14:05:32 +0000 (22:05 +0800)
committerhi-rustin <rustin.liu@gmail.com>
Mon, 5 Apr 2021 14:57:14 +0000 (22:57 +0800)
Signed-off-by: Rustin-Liu <rustin.liu@gmail.com>
test.rs [new file with mode: 0644]

diff --git a/test.rs b/test.rs
new file mode 100644 (file)
index 0000000..bc7f5af
--- /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