diff --git a/src/main.rs b/src/main.rs index d3ad16f..3319d61 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,15 +4,18 @@ use std::{ f32::consts::FRAC_PI_2, io::stdout, net::{Ipv4Addr, SocketAddr, UdpSocket}, + num::ParseIntError, + str::FromStr, thread::sleep, time::Duration, }; -use clap::Parser; +use clap::{Parser, Subcommand}; use image::{Pixel, Rgb, RgbImage}; use rand::Rng; -use splink_client::{Layout, send_frame}; +use splink_client::{send_frame, Layout}; +use thiserror::Error; /// Blinkenwall v3 prototype client #[derive(Parser, Debug)] @@ -28,8 +31,56 @@ struct Args { /// Controller's address remote_addr: SocketAddr, + + /// The action to perform + #[clap(subcommand, rename_all = "kebab-case")] + action: Action, } +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +struct Color { + r: u8, + g: u8, + b: u8, +} + +#[derive(Clone, Debug, Error)] +enum ColorError { + #[error("Wrong parameter length")] + WrongLength, + #[error("Illegal integer")] + BadNumber(#[from] ParseIntError), +} + +impl FromStr for Color { + type Err = ColorError; + + fn from_str(s: &str) -> Result { + let s = s.strip_prefix('#').unwrap_or(s); + + if s.len() != 6 { + return Err(ColorError::WrongLength); + } + + let r = u8::from_str_radix(&s[0..2], 16)?; + let g = u8::from_str_radix(&s[2..4], 16)?; + let b = u8::from_str_radix(&s[4..6], 16)?; + + Ok(Self { r, g, b }) + } +} + +impl From for Rgb { + fn from(c: Color) -> Rgb { + Rgb([c.r, c.g, c.b]) + } +} + +#[derive(Clone, Debug, PartialEq, Eq, Subcommand)] +enum Action { + Solid { color: Color }, + Clear, +} fn get_frame(layout: Layout, frame: u32) -> RgbImage { #![allow( @@ -105,20 +156,18 @@ fn main() -> anyhow::Result<()> { num_panels_v: 1, }; - for frame in 0.. { - let image = get_frame(layout, frame); - - print_image(&image); - - let frame_num: u32 = rand::thread_rng().gen(); - send_frame(&socket, layout, frame_num, &image)?; - - sleep(Duration::from_millis(16)); + match args.action { + Action::Solid { color } => { + let image = RgbImage::from_pixel(layout.width_px(), layout.height_px(), color.into()); + let frame_num: u32 = rand::thread_rng().gen(); + send_frame(&socket, layout, frame_num, &image)?; + } + Action::Clear => { + let image = RgbImage::new(layout.width_px(), layout.height_px()); + let frame_num: u32 = rand::thread_rng().gen(); + send_frame(&socket, layout, frame_num, &image)?; + } } - let image = RgbImage::from_fn(96, 64, |_x, y| { - [Rgb([0, 3, 1]), Rgb([1, 3, 0]), Rgb([3, 0, 1])][y as usize % 3] - }); - Ok(()) }