mod scanner; mod fade; mod color_wipe; mod rainbow; mod fill_random; mod fill_unstable; mod blink; mod rain; use serde_derive::{Deserialize, Serialize}; use std::fmt; use std::ops::{Div, Index, IndexMut, SubAssign}; use crate::patterns::blink::Blink; use crate::patterns::color_wipe::ColorWipe; use crate::patterns::fade::Fade; use crate::patterns::fill_random::FillRandom; use crate::patterns::fill_unstable::FillUnstable; use crate::patterns::rainbow::Rainbow; use crate::patterns::scanner::Scanner; #[derive(Serialize, Deserialize, Debug, Eq, Hash, PartialEq, Copy, Clone)] #[serde(tag = "type")] pub(crate) enum Patterns { Rainbow(Rainbow), Fade(Fade), ColorWipe(ColorWipe), Scanner(Scanner), FillRandom(FillRandom), FillUnstable(FillUnstable), Blink(Blink), } pub trait Pattern : Iterator { type Strip; fn init(&self) -> Option; } impl Iterator for Patterns { type Item = Strip; fn next(&mut self) -> Option { match self { Patterns::Rainbow(p) => p.next(), Patterns::Fade(p) => p.next(), Patterns::ColorWipe(p) => p.next(), Patterns::Scanner(p) => p.next(), Patterns::FillRandom(p) => p.next(), Patterns::FillUnstable(p) => p.next(), Patterns::Blink(p) => p.next(), } } } impl Pattern for Patterns { type Strip = Strip; fn init(&self) -> Option { match self { Patterns::Rainbow(p) => p.init(), Patterns::Fade(p) => p.init(), Patterns::ColorWipe(p) => p.init(), Patterns::Scanner(p) => p.init(), Patterns::FillRandom(p) => p.init(), Patterns::FillUnstable(p) => p.init(), Patterns::Blink(p) => p.init(), } } } /// /// a struct for an RGB color #[derive(Clone, Copy, Debug, Serialize, Deserialize, Default, Eq, Hash, PartialEq)] pub struct PixelColor { pub(crate) red: u8, pub(crate) green: u8, pub(crate) blue: u8, } impl fmt::Display for PixelColor { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "[{},{},{}]", self.red, self.green, self.blue) } } impl Div for PixelColor { type Output = PixelColor; fn div(self, rhs: u8) -> Self::Output { PixelColor { red: self.red / rhs, green: self.green / rhs, blue: self.blue / rhs, } } } impl SubAssign for PixelColor { fn sub_assign(&mut self, rhs: Self) { println!("self.red {}, red {}", self.red, rhs.red); self.red = self.red.saturating_sub(rhs.red); self.green = self.red.saturating_sub(rhs.green); self.blue = self.red.saturating_sub(rhs.blue); } } /// /// a basic newtype based on a fix array size. /// #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] pub struct Strip([Option; N]); impl Default for Strip { fn default() -> Self { Strip([None; N]) } } impl Index for Strip { type Output = Option; fn index(&self, index: usize) -> &Self::Output { &self.0[index] } } impl IndexMut for Strip { fn index_mut(&mut self, index: usize) -> &mut Option { &mut self.0[index] } } impl Strip { pub fn to_array(self) -> Vec { let mut data: Vec = vec![]; for i in 0..N { let color = self[i].unwrap_or(PixelColor::default()); data.append(&mut vec![color.green, color.red, color.blue]); } data } pub fn new(color: PixelColor) -> Strip { Strip { 0: [Some(color); N] } } pub fn fill(&mut self, color: PixelColor) { self.0.fill(Some(color)); } }