use serde_derive::{Deserialize, Serialize}; use std::cmp::{max, min, Ordering}; use std::convert::Infallible; use std::fmt; use std::ops::Div; #[derive(Serialize, Deserialize, Debug)] #[serde(tag = "type")] pub(crate) enum Patterns { Rainbow(Rainbow), Fade(Fade), ColorWipe(ColorWipe), Scanner(Scanner), } 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(), } } } #[derive(Clone, Copy, Debug, Default, Serialize, Deserialize)] pub struct PixelColor { pub(crate) red: u8, pub(crate) green: u8, pub(crate) blue: u8, } impl PixelColor { fn new() -> Self { Default::default() } } 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, } } } #[derive(Copy, Clone)] pub struct Strip { pub strip: [PixelColor; N], } impl Strip { pub fn to_array(self) -> Vec { let mut data: Vec = vec![]; for i in 0..N { data.append(&mut vec![ self.strip[i].green, self.strip[i].red, self.strip[i].blue, ]); } data } pub fn fill(&mut self, color: PixelColor) { self.strip = [color; N]; } } impl Default for Strip { fn default() -> Self { Strip { strip: [PixelColor::new(); N], } } } /// Rainbow pattern ///////////////////////////////////////////////// #[derive(Serialize, Deserialize, Debug)] pub struct Rainbow { pub(crate) current_iteration: usize, pub(crate) max_iteration: Option, pub(crate) step: Option, } impl Iterator for Rainbow { type Item = Strip; fn next(&mut self) -> Option { if let Some(nbr_iteration) = self.max_iteration { if nbr_iteration == self.current_iteration { return None; } } let mut strip = Strip::default(); let step = self.step.unwrap_or(255 / N); for i in 0..N { let pos = (i * step + self.current_iteration) as u8; strip.strip[i] = wheel(pos) } self.current_iteration += 1; Some(strip) } } fn wheel(index: u8) -> PixelColor { let pos = 255 - index; match pos { 0..=85 => PixelColor { red: 255 - (pos * 3), green: 0, blue: pos * 3, }, 86..=170 => { let pos = pos - 85; PixelColor { red: 0, green: pos * 3, blue: 255 - (pos * 3), } } _ => { let pos = pos - 170; PixelColor { red: pos * 3, green: 255 - (pos * 3), blue: 0, } } } } ////////////////////////////////////////////////////////////////////////// /// Colorwipe pattern //////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// #[derive(Serialize, Deserialize, Debug)] pub struct ColorWipe { pub(crate) current_iteration: usize, pub(crate) color: PixelColor, pub(crate) infinite: bool, } impl Iterator for ColorWipe { type Item = Strip; fn next(&mut self) -> Option { let mut strip = Strip::default(); if self.infinite { self.current_iteration %= N; } else if self.current_iteration >= N { return None; } for i in 0..self.current_iteration { strip.strip[i] = self.color; } self.current_iteration += 1; Some(strip) } } ////////////////////////////////////////////////////////////////////////// /// fade pattern //////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// #[derive(Serialize, Deserialize, Debug)] pub struct Fade { pub(crate) current_iteration: usize, pub(crate) nbr_iterations: usize, pub(crate) begin_color: PixelColor, pub(crate) end_color: PixelColor, } fn fade_value(value_start: u8, value_end: u8, index: usize, nbr_iter: usize) -> u8 { ((value_start as usize * (nbr_iter - index) + value_end as usize * index) / nbr_iter) as u8 } impl Iterator for Fade { type Item = Strip; fn next(&mut self) -> Option { let mut strip = Strip::default(); if self.current_iteration >= self.nbr_iterations { return None; } let red = fade_value( self.begin_color.red, self.end_color.red, self.current_iteration, self.nbr_iterations, ); let green = fade_value( self.begin_color.green, self.end_color.green, self.current_iteration, self.nbr_iterations, ); let blue = fade_value( self.begin_color.blue, self.end_color.blue, self.current_iteration, self.nbr_iterations, ); let current_color = PixelColor { red, green, blue }; strip.fill(current_color); self.current_iteration += 1; Some(strip) } } ////////////////////////////////////////////////////////////////////////// /// scanner pattern //////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// #[derive(Serialize, Deserialize, Debug)] pub struct Scanner { pub(crate) current_iteration: usize, pub(crate) color: PixelColor, pub(crate) background_color: Option, } impl Iterator for Scanner { type Item = Strip; fn next(&mut self) -> Option { let mut strip = Strip::::default(); if let Some(c) = self.background_color { strip.fill(c); } else { strip.fill(PixelColor::default()); } let current_led = self.current_iteration % N; let min_led; if current_led < 8 { min_led = 0; } else { min_led = current_led - 8; } let mut c = self.color; for i in min_led..current_led { strip.strip[i] = c; c = c / 2; println!("{}", c); } self.current_iteration += 1; Some(strip) } }