mod blink; mod color_wipe; mod fade; mod fade_random; mod fade_unstable; mod fill_random; mod fill_unstable; mod rain; mod rainbow; mod ring; mod ring_scanner; mod scanner; mod stars_random; use crate::patterns::blink::Blink; use crate::patterns::color_wipe::ColorWipe; use crate::patterns::fade::Fade; use crate::patterns::fade_random::FadeRandom; use crate::patterns::fade_unstable::FadeUnstable; use crate::patterns::fill_random::FillRandom; use crate::patterns::fill_unstable::FillUnstable; use crate::patterns::rain::Rain; use crate::patterns::rainbow::Rainbow; use crate::patterns::ring::Ring; use crate::patterns::ring_scanner::RingScanner; use crate::patterns::scanner::Scanner; use crate::patterns::stars_random::StarsRandom; use crate::pixel_color::PixelColor; use serde_derive::{Deserialize, Serialize}; use std::ops::{Index, IndexMut}; #[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), Rain(Rain), FadeRandom(FadeRandom), FadeUnstable(FadeUnstable), Ring(Ring), RingScanner(RingScanner), StarsRandom(StarsRandom), } /// Pattern that have to be implemented /// /// /// /// pub trait Pattern: Iterator { type Strip; fn init(&mut self) -> Option { None } fn is_last_iteration(&self) -> bool; } #[macro_export] macro_rules! impl_pattern_init_background { ($generic: tt) => { fn init(&mut self) -> Option { if let Some(color) = self.background_color { Some(Strip::::new(color)) } else { None } } }; } #[macro_export] macro_rules! impl_pattern_last_iteration { ($name:ty) => { fn is_last_iteration(&self) -> bool { match self.max_iteration { None => false, Some(max_iter) => { if self.current_iteration >= max_iter { true } else { false } } } } }; } 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(), Patterns::Rain(p) => p.next(), Patterns::FadeRandom(p) => p.next(), Patterns::FadeUnstable(p) => p.next(), Patterns::Ring(p) => p.next(), Patterns::RingScanner(p) => p.next(), Patterns::StarsRandom(p) => p.next(), } } } impl Pattern for Patterns { type Strip = Strip; fn init(&mut 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(), Patterns::Rain(p) => p.init(), Patterns::FadeRandom(p) => p.init(), Patterns::FadeUnstable(p) => p.init(), Patterns::Ring(p) => p.init(), Patterns::RingScanner(p) => p.init(), Patterns::StarsRandom(p) => p.init(), } } fn is_last_iteration(&self) -> bool { match self { Patterns::Rainbow(p) => p.is_last_iteration(), Patterns::Fade(p) => p.is_last_iteration(), Patterns::ColorWipe(p) => p.is_last_iteration(), Patterns::Scanner(p) => p.is_last_iteration(), Patterns::FillRandom(p) => p.is_last_iteration(), Patterns::FillUnstable(p) => p.is_last_iteration(), Patterns::Blink(p) => p.is_last_iteration(), Patterns::Rain(p) => p.is_last_iteration(), Patterns::FadeRandom(p) => p.is_last_iteration(), Patterns::FadeUnstable(p) => p.is_last_iteration(), Patterns::Ring(p) => p.is_last_iteration(), Patterns::RingScanner(p) => p.is_last_iteration(), Patterns::StarsRandom(p) => p.is_last_iteration(), } } } /// /// 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)); } }