diff --git a/src/main.rs b/src/main.rs index acb0326..848d29a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,25 +10,48 @@ extern crate structopt; extern crate hidapi; extern crate users; - -use std::path::PathBuf; use std::process; use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "rust-footswitch")] struct Opt { - /// Read all pedals - #[structopt(short = "r", long = "read")] - read: bool, - /// Prints a table of all keys with rows #[structopt(short = "l", long = "listkeys")] listkeys: Option, - /// Select pedal (left: 1, middle: 2, right: 3) - #[structopt(short = "p", long = "pedal", parse(from_os_str))] - output: Option, + #[structopt(subcommand)] + cmd: Option, +} + +#[derive(StructOpt, Debug)] +enum Command { + /// Write to the footpedal + #[structopt(name = "write")] + Write { + /// Specify pedal to modify with following command. Possible values: [0 | 1 | 2] + #[structopt(short = "p", long = "pedal")] + pedal: Vec, + + /// Command to apply. Possible values: [set_key | del_key | append_key | append_str] + #[structopt(short = "c", long = "command")] + command: Vec, + + /// Value to apply + #[structopt(short = "v", long = "value")] + value: Vec, + }, + + #[structopt(name = "read")] + Read { + /// Read all pedals + #[structopt(short = "a", long = "all")] + all: bool, + + /// Specify specific pedals. Possible values: [0 | 1 | 2] + #[structopt(short = "p", long = "pedal")] + pedals: Vec, + } } fn main() { @@ -66,23 +89,74 @@ fn main() { } } - let dev = api.open_path(dev_path.as_str()).unwrap(); println!("Succesfully opened device."); - //ToDo: This part of the code is just there to test functions - pedals.set_key(0, "b"); - pedals.write_pedals(& dev); // All options that need the device to be open - if opt.read { - pedals.read_pedals(& dev); + match opt.cmd { + Some(Command::Write {pedal: ped_list, command: cmd_list, value: val_list}) => { + if ped_list.len() != cmd_list.len() && ped_list.len() != val_list.len() { + eprintln!("Error: You must define as much pedals as you define commands and as you define values!"); + process::exit(0); + } + + for (i, cmd) in cmd_list.iter().enumerate() { + match cmd as &str { + "wr_key" => { + pedals.set_key(i, val_list[i].as_str()); + } + "del_key" => { + } + "append_key" => { + } + "append_str" => { + } + _ => { + eprintln!("Error: Unkonwn command!"); + process::exit(0); + } + } + } + + // Since we ran the Write command without any errors, we are now writing everything + pedals.write_pedals(& dev); + + println!("Succesfully wrote everything to footpedal!"); + println!("The current state of the device is shown below.\n"); + + // Show user current state of pedal + pedals.read_pedals(&dev, vec![0,1,2]); + + }, + Some(Command::Read {all: all_var, pedals: ped_list}) => { + if ped_list.len() > 3 { + eprintln!("Error: Number of pedals may not be bigger than 3!"); + process::exit(0); + } + + if all_var { + pedals.read_pedals(&dev, vec![0,1,2]); + } + else if ped_list.len() > 0 { + pedals.read_pedals(&dev, ped_list) + } + else { + eprintln!("Error: You did not specify any command. Run './footswitch-rs read --help' for more information"); + process::exit(0); + } + }, + None => { + eprintln!("Error: You did not specify any command. Run './footswitch-rs --help' for more information."); + process::exit(0); + } } } /// Checks if user is super user fn check_sudo() { if users::get_current_uid() != 0 { - panic!("Please execute this application as super user!"); + eprintln!("Error: Please execute this application as super user!"); + process::exit(0); } } diff --git a/src/pedal_operations.rs b/src/pedal_operations.rs index 0ea5927..27758ff 100644 --- a/src/pedal_operations.rs +++ b/src/pedal_operations.rs @@ -1,6 +1,7 @@ #[path = "key_operations.rs"] mod key_operations; extern crate hidapi; +use std::process; pub struct PedalsData { header: [u8; 8], @@ -49,7 +50,7 @@ impl Pedals { } } - fn read_pedal(&self, dev: & hidapi::HidDevice, ped:u8) -> [u8; 8] { + pub fn read_pedal(&self, dev: & hidapi::HidDevice, ped:& u8) -> [u8; 8] { let mut buf = [0u8; 8]; let mut query = [0x01u8, 0x82, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00]; @@ -65,26 +66,49 @@ impl Pedals { } /// Read the current values of the pedals - pub fn read_pedals(&self, dev: & hidapi::HidDevice) { - let column_width = 15; - let total_width = (column_width+3)*3; + pub fn read_pedals(&self, dev: & hidapi::HidDevice, peds: Vec) { + // This is kind of hacky, but for number of pedals == 2, the table shifts. + let total_width = 62 + (peds.len() == 2) as usize; + let column_width = 60 / peds.len() + (3 - peds.len()); // Print header - println!(" {}", "-".repeat(total_width)); - println!(" ‖{name:^width$}‖", name = "Programmed Keys", width = total_width - 2); - println!(" {}", "-".repeat(total_width)); + println!(" ╔{}╗", "═".repeat(total_width)); + println!(" ║{name:^width$}║", name = "Programmed Keys", width = total_width); + println!(" ╠{}╣", "═".repeat(total_width)); + + // Print space before pedal number row + print!(" "); + + // Print pedal numbers + for i in peds.iter() { + // Check if passed pedal number is valid + if *i > 2 { + eprintln!("Error: Pedal value {} is larger than 2 and thus not valid!", i); + process::exit(0); + } + + // Print pedal numbers + print!("│{ped_nr:^-width$}", ped_nr = i, width = column_width); + } + + println!("│\n ├{}┤", "─".repeat(total_width)); + + // Print space before value row + print!(" "); // Read and print keys - for i in 0..3 { + for i in peds.iter() { + // Read value from pedal and directly translate it to a key let key_name = match key_operations::print_key(&self.read_pedal(dev, i)) { Some(key) => key, None => "< None >".to_string(), }; - print!(" ‖ {name:^-width$}", name = key_name, width = column_width); + + print!("│{name:^-width$}", name = key_name, width = column_width); } // Print simple footer - println!("‖\n {}", "-".repeat(total_width)); + println!("│\n └{}┘", "─".repeat(total_width)); } fn write_pedal(&self, dev: & hidapi::HidDevice, ped:usize) { @@ -125,7 +149,8 @@ impl Pedals { self.ped_data[ped].data[3] = encoded_key; } else { - //ToDo: add "print list" if value is not recognized + eprintln!("Error: Key '{}' is not recognized! Please provide a valid key, listed in './footswitch-rs --listkeys 4'", key); + process::exit(0); } }