use std::fmt; #[derive(Clone, Copy, Debug)] 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 Default for PixelColor { fn default() -> Self { PixelColor { red: 0, green: 0, blue: 0, } } } #[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].red, self.strip[i].green, self.strip[i].blue, ]); } data } } impl Default for Strip { fn default() -> Self { Strip { strip: [PixelColor::new(); N], } } } pub struct RainbowPattern { pub(crate) current_iteration: usize, pub(crate) max_iteration: Option, } impl Iterator for RainbowPattern { 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 = 255 / N; for i in 0..N { let pos = (i * step + self.current_iteration) as u8; strip.strip[i] = wheel(pos) } self.current_iteration = 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; return PixelColor { red: pos * 3, green: 255 - (pos * 3), blue: 0, }; } } }