diff --git a/src/conf.rs b/src/conf.rs index 02ea741..2b449ec 100644 --- a/src/conf.rs +++ b/src/conf.rs @@ -19,10 +19,8 @@ pub struct Conf { pub fn load_config(path: &str) -> Result> { let settings = Config::builder() .add_source(config::File::with_name(path)) - .build()?; - - let conf = settings.try_deserialize::()?; - - + .build()?; + + let conf : Conf = settings.try_deserialize()?; Ok(conf) } diff --git a/src/errors.rs b/src/errors.rs new file mode 100644 index 0000000..9a9c179 --- /dev/null +++ b/src/errors.rs @@ -0,0 +1,36 @@ +use std::error::Error; +use std::fmt; +use redis::RedisError; + +#[derive(Debug)] +pub enum LJError { + ConfigFileMissing, + RedisConnect(RedisError) +} + +impl fmt::Display for LJError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use LJError::*; + + match self { + ConfigFileMissing => { + write!(f, "first argument must be a TOML config file \ + (see copyme.Settings.toml)") + }, + RedisConnect(err) => { + write!(f, "unable to connect to redis server: {err}") + } + } + } +} + +impl Error for LJError { + fn source(&self) -> Option<&(dyn Error + 'static)> { + use LJError::*; + + match self { + ConfigFileMissing => None, + RedisConnect(err) => Some(err) + } + } +} diff --git a/src/lib.rs b/src/lib.rs index 524f793..f3347b9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,2 +1,3 @@ pub mod conf; pub mod redis_ctrl; +pub mod errors; diff --git a/src/main.rs b/src/main.rs index 374e9a0..6b5fa5e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,10 @@ -mod conf; /// /// Configure udev: /// https://github.com/Grix/helios_dac/blob/master/docs/udev_rules_for_linux.md /// mod redis_ctrl; +mod conf; +mod errors; use helios_dac::NativeHeliosDacController; use helios_dac::{ @@ -15,43 +16,41 @@ use helios_dac::{ }; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; +use redis_ctrl::{RedisCtrl,Order}; +use conf::{load_config,Conf}; +use errors::LJError; -use conf::{load_config, Conf}; -use redis_ctrl::{Order, RedisCtrl}; - -const CENTER: (u16, u16) = (2000, 2000); +const CENTER : (u16,u16) = (2000, 2000); pub fn main() { - let config = match load_config("Settings") { - Ok(c) => c, - Err(err) => { - panic!("Unable to load config file: {:?}", err) - } - }; - - let rs = match RedisCtrl::new() { - Ok(rs) => rs, - Err(err) => { - panic!("Unable to connect to redis: {:?}", err); - } - }; - - match run_dac(config, rs) { - Ok(()) => {} - Err(err) => { - panic!("Error: {:?}", err) - } + match run_all() { + Ok(()) => {}, + Err(err) => { + println!("Error: {}", err); + } } } -fn run_dac(config: Conf, mut rs: RedisCtrl) -> Result<(), Box> { +fn run_all() -> Result<(), Box> { + let Some(filename) = std::env::args().nth(1) else { + return Err(Box::new(LJError::ConfigFileMissing)); + }; + let config = load_config(&filename)?; + let rs = RedisCtrl::new()?; + + run_dac(config, rs) +} + +fn run_dac( + config: Conf, + mut rs: RedisCtrl +) -> Result<(), Box> { let running = Arc::new(AtomicBool::new(true)); let r = running.clone(); ctrlc::set_handler(move || { r.store(false, Ordering::SeqCst); - }) - .expect("Error setting Ctrl-C handler"); + })?; let controller = NativeHeliosDacController::new()?; let devices = controller.list_devices()?; @@ -60,18 +59,20 @@ fn run_dac(config: Conf, mut rs: RedisCtrl) -> Result<(), Box Result<(), Box Result> { - let line = rs.get("/pl/0/0")?; +fn get_next_frame( + config: &Conf, + speed: u32, + rs: &mut RedisCtrl, + _black: bool +) -> Result> { + + let line = rs.get(&format!("/pl/{}/0", config.laser_id))?; let line: Vec = line.iter().map(tuple_to_point).collect(); let mut line2 = vec![]; @@ -91,18 +98,20 @@ fn get_next_frame(speed: u32, rs: &mut RedisCtrl) -> Result Point { let (x, y, col) = tpl; - - let r = (col >> 16) as u8; - let g = ((col >> 8) & 255) as u8; - let b = (col & 255) as u8; - - let x = CENTER.0 + *x as u16; - let y = CENTER.1 + *y as u16; + + let r = (col >> 16) as u8 ; + let g = ((col >> 8) & 255) as u8 ; + let b = (col & 255) as u8 ; + + let x = CENTER.0 + *x as u16 * 2; + let y = CENTER.1 + *y as u16 * 2; if x >= 4096 || y >= 4096 { println!("WARN: coordinate out of range: {} {}", x, y); diff --git a/src/redis_ctrl.rs b/src/redis_ctrl.rs index 238bd8a..5653a0d 100644 --- a/src/redis_ctrl.rs +++ b/src/redis_ctrl.rs @@ -1,5 +1,6 @@ use redis::{Client, Commands, Connection}; use ron::de::from_str; +use crate::errors::LJError; #[repr(u8)] #[derive(Debug, PartialEq)] @@ -21,22 +22,22 @@ impl TryFrom for Order { fn try_from(value: u8) -> Result { use Order::*; - if value > 8 { - return Err("order out of range".to_string()); - } - - Ok(match value { - 0 => Draw, - 1 => Edh, - 2 => Black, - 3 => Grid, - 4 => Resampler, - 5 => ClientKey, - 6 => Intensity, - 7 => Kpps, - 8 => ColorBalance, - _ => panic!("Can't be there"), - }) + if value > 8 { + return Err("order out of range".to_string()); + } + + Ok(match value { + 0 => Draw, + 1 => Edh, + 2 => Black, + 3 => Grid, + 4 => Resampler, + 5 => ClientKey, + 6 => Intensity, + 7 => Kpps, + 8 => ColorBalance, + _ => unreachable!() + }) } } @@ -49,8 +50,10 @@ pub struct RedisCtrl { impl RedisCtrl { pub fn new() -> Result> { - let client = Client::open("redis://127.0.0.1/")?; - let connection = client.get_connection()?; + let client = Client::open("redis://127.0.0.1/") + .map_err(| err | LJError::RedisConnect(err))?; + let connection = client.get_connection() + .map_err(| err | LJError::RedisConnect(err))?; Ok(RedisCtrl { client, connection }) }