ectool: Use clap derive syntax
Co-authored-by: Tim Crawford <tcrawford@system76.com>
This commit is contained in:
committed by
Jeremy Soller
parent
cbad8e09be
commit
47b070418a
92
tool/Cargo.lock
generated
92
tool/Cargo.lock
generated
@ -42,13 +42,28 @@ checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"bitflags",
|
||||
"clap_derive",
|
||||
"clap_lex",
|
||||
"indexmap",
|
||||
"once_cell",
|
||||
"strsim",
|
||||
"termcolor",
|
||||
"textwrap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "3.2.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.2.4"
|
||||
@ -70,6 +85,12 @@ version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
@ -107,6 +128,12 @@ version = "0.2.148"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b"
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||
|
||||
[[package]]
|
||||
name = "os_str_bytes"
|
||||
version = "6.5.1"
|
||||
@ -119,6 +146,48 @@ version = "0.3.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b1106fec09662ec6dd98ccac0f81cef56984d0b49f75c92d8cbad76e20c005c"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_hwio"
|
||||
version = "0.1.6"
|
||||
@ -131,6 +200,17 @@ version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "system76_ectool"
|
||||
version = "0.3.8"
|
||||
@ -157,6 +237,18 @@ version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
|
@ -16,7 +16,7 @@ name = "system76_ectool"
|
||||
required-features = ["std", "hidapi", "clap"]
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "3.2", optional = true }
|
||||
clap = { version = "3.2", features = ["derive"], optional = true }
|
||||
libc = { version = "0.2", optional = true }
|
||||
# NOTE: Upgrading to 2.x blocked on Ubuntu shipping newer hidapi
|
||||
hidapi = { version = "1.5", default-features = false, features = ["linux-shared-hidraw"], optional = true }
|
||||
|
246
tool/src/main.rs
246
tool/src/main.rs
@ -2,7 +2,7 @@
|
||||
|
||||
#![allow(clippy::uninlined_format_args)]
|
||||
|
||||
use clap::{Arg, App, AppSettings, SubCommand};
|
||||
use clap::{AppSettings, Parser};
|
||||
use ectool::{
|
||||
Access,
|
||||
AccessHid,
|
||||
@ -303,115 +303,96 @@ fn parse_color(s: &str) -> Result<(u8, u8, u8), String> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Parser)]
|
||||
#[clap(rename_all = "snake_case")]
|
||||
enum SubCommand {
|
||||
Console,
|
||||
Fan {
|
||||
index: u8,
|
||||
duty: Option<u8>,
|
||||
},
|
||||
Flash {
|
||||
path: String,
|
||||
},
|
||||
FlashBackup {
|
||||
path: String,
|
||||
},
|
||||
Info,
|
||||
Keymap {
|
||||
layer: u8,
|
||||
output: u8,
|
||||
input: u8,
|
||||
value: Option<String>,
|
||||
},
|
||||
LedColor {
|
||||
index: u8,
|
||||
#[clap(validator = |x| parse_color(x).and(Ok(())))]
|
||||
value: Option<String>,
|
||||
},
|
||||
LedValue {
|
||||
index: u8,
|
||||
value: Option<u8>,
|
||||
},
|
||||
LedMode {
|
||||
layer: u8,
|
||||
#[clap(requires = "speed")]
|
||||
mode: Option<u8>,
|
||||
speed: Option<u8>,
|
||||
},
|
||||
LedSave,
|
||||
Reset,
|
||||
Matrix,
|
||||
Print {
|
||||
#[clap(required = true)]
|
||||
message: Vec<String>,
|
||||
},
|
||||
SetNoInput {
|
||||
#[clap(parse(try_from_str))]
|
||||
value: bool,
|
||||
},
|
||||
Security {
|
||||
state: Option<String>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(clap::ArgEnum, Clone)]
|
||||
enum AccessMode {
|
||||
LpcLinux,
|
||||
LpcSim,
|
||||
Hid,
|
||||
}
|
||||
|
||||
#[derive(Parser)]
|
||||
#[clap(name = "system76_ectool", setting = AppSettings::SubcommandRequired)]
|
||||
struct Args {
|
||||
#[clap(
|
||||
long = "access",
|
||||
arg_enum,
|
||||
default_value = "lpc-linux",
|
||||
)]
|
||||
access: AccessMode,
|
||||
#[clap(subcommand)]
|
||||
subcommand: SubCommand,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let matches = App::new("system76_ectool")
|
||||
.setting(AppSettings::SubcommandRequired)
|
||||
.arg(Arg::with_name("access")
|
||||
.long("access")
|
||||
.possible_values(["lpc-linux", "lpc-sim", "hid"])
|
||||
.default_value("lpc-linux")
|
||||
)
|
||||
.subcommand(SubCommand::with_name("console"))
|
||||
.subcommand(SubCommand::with_name("fan")
|
||||
.arg(Arg::with_name("index")
|
||||
.value_parser(clap::value_parser!(u8))
|
||||
.required(true)
|
||||
)
|
||||
.arg(Arg::with_name("duty")
|
||||
.value_parser(clap::value_parser!(u8))
|
||||
)
|
||||
)
|
||||
.subcommand(SubCommand::with_name("flash")
|
||||
.arg(Arg::with_name("path")
|
||||
.required(true)
|
||||
)
|
||||
)
|
||||
.subcommand(SubCommand::with_name("flash_backup")
|
||||
.arg(Arg::with_name("path")
|
||||
.required(true)
|
||||
)
|
||||
)
|
||||
.subcommand(SubCommand::with_name("info"))
|
||||
.subcommand(SubCommand::with_name("keymap")
|
||||
.arg(Arg::with_name("layer")
|
||||
.value_parser(clap::value_parser!(u8))
|
||||
.required(true)
|
||||
)
|
||||
.arg(Arg::with_name("output")
|
||||
.value_parser(clap::value_parser!(u8))
|
||||
.required(true)
|
||||
)
|
||||
.arg(Arg::with_name("input")
|
||||
.value_parser(clap::value_parser!(u8))
|
||||
.required(true)
|
||||
)
|
||||
.arg(Arg::with_name("value"))
|
||||
)
|
||||
.subcommand(SubCommand::with_name("led_color")
|
||||
.arg(Arg::with_name("index")
|
||||
.value_parser(clap::value_parser!(u8))
|
||||
.required(true)
|
||||
)
|
||||
.arg(Arg::with_name("value")
|
||||
.value_parser(parse_color)
|
||||
)
|
||||
)
|
||||
.subcommand(SubCommand::with_name("led_value")
|
||||
.arg(Arg::with_name("index")
|
||||
.value_parser(clap::value_parser!(u8))
|
||||
.required(true)
|
||||
)
|
||||
.arg(Arg::with_name("value")
|
||||
.value_parser(clap::value_parser!(u8))
|
||||
)
|
||||
)
|
||||
.subcommand(SubCommand::with_name("led_mode")
|
||||
.arg(Arg::with_name("layer")
|
||||
.value_parser(clap::value_parser!(u8))
|
||||
.required(true)
|
||||
)
|
||||
.arg(Arg::with_name("mode")
|
||||
.value_parser(clap::value_parser!(u8))
|
||||
.requires("speed")
|
||||
)
|
||||
.arg(Arg::with_name("speed")
|
||||
.value_parser(clap::value_parser!(u8))
|
||||
)
|
||||
)
|
||||
.subcommand(SubCommand::with_name("led_save"))
|
||||
.subcommand(SubCommand::with_name("reset"))
|
||||
.subcommand(SubCommand::with_name("matrix"))
|
||||
.subcommand(SubCommand::with_name("print")
|
||||
.arg(Arg::with_name("message")
|
||||
.required(true)
|
||||
.multiple(true)
|
||||
)
|
||||
)
|
||||
.subcommand(SubCommand::with_name("set_no_input")
|
||||
.arg(Arg::with_name("value")
|
||||
.possible_values(["true", "false"])
|
||||
.required(true)
|
||||
)
|
||||
)
|
||||
.subcommand(SubCommand::with_name("security")
|
||||
.arg(Arg::with_name("state")
|
||||
.possible_values(["lock", "unlock"])
|
||||
)
|
||||
)
|
||||
.get_matches();
|
||||
//.subcommand(Command::new("security").arg(Arg::new("state").value_parser(["lock", "unlock"])))
|
||||
|
||||
let args = Args::parse();
|
||||
|
||||
let get_ec = || -> Result<_, Error> {
|
||||
unsafe {
|
||||
match matches.value_of("access").unwrap() {
|
||||
"lpc-linux" => {
|
||||
match args.access {
|
||||
AccessMode::LpcLinux => {
|
||||
let access = AccessLpcLinux::new(Duration::new(1, 0))?;
|
||||
Ok(Ec::new(access)?.into_dyn())
|
||||
},
|
||||
"lpc-sim" => {
|
||||
AccessMode::LpcSim => {
|
||||
let access = AccessLpcSim::new(Duration::new(1, 0))?;
|
||||
Ok(Ec::new(access)?.into_dyn())
|
||||
},
|
||||
"hid" => {
|
||||
AccessMode::Hid => {
|
||||
let api = HidApi::new()?;
|
||||
for info in api.device_list() {
|
||||
#[allow(clippy::single_match)]
|
||||
@ -433,7 +414,6 @@ fn main() {
|
||||
}
|
||||
Err(hidapi::HidError::HidApiErrorEmpty.into())
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -445,18 +425,16 @@ fn main() {
|
||||
}
|
||||
};
|
||||
|
||||
match matches.subcommand() {
|
||||
Some(("console", _sub_m)) => match unsafe { console(&mut ec) } {
|
||||
match args.subcommand {
|
||||
SubCommand::Console => match unsafe { console(&mut ec) } {
|
||||
Ok(()) => (),
|
||||
Err(err) => {
|
||||
eprintln!("failed to read console: {:X?}", err);
|
||||
process::exit(1);
|
||||
},
|
||||
},
|
||||
Some(("fan", sub_m)) => {
|
||||
let index = sub_m.value_of("index").unwrap().parse::<u8>().unwrap();
|
||||
let duty_opt = sub_m.value_of("duty").map(|x| x.parse::<u8>().unwrap());
|
||||
match duty_opt {
|
||||
SubCommand::Fan { index, duty } => {
|
||||
match duty {
|
||||
Some(duty) => match unsafe { fan_set(&mut ec, index, duty) } {
|
||||
Ok(()) => (),
|
||||
Err(err) => {
|
||||
@ -473,9 +451,8 @@ fn main() {
|
||||
},
|
||||
}
|
||||
},
|
||||
Some(("flash", sub_m)) => {
|
||||
let path = sub_m.value_of("path").unwrap();
|
||||
match unsafe { flash(&mut ec, path, SpiTarget::Main) } {
|
||||
SubCommand::Flash { path } => {
|
||||
match unsafe { flash(&mut ec, &path, SpiTarget::Main) } {
|
||||
Ok(()) => (),
|
||||
Err(err) => {
|
||||
eprintln!("failed to flash '{}': {:X?}", path, err);
|
||||
@ -483,9 +460,8 @@ fn main() {
|
||||
},
|
||||
}
|
||||
},
|
||||
Some(("flash_backup", sub_m)) => {
|
||||
let path = sub_m.value_of("path").unwrap();
|
||||
match unsafe { flash(&mut ec, path, SpiTarget::Backup) } {
|
||||
SubCommand::FlashBackup { path } => {
|
||||
match unsafe { flash(&mut ec, &path, SpiTarget::Backup) } {
|
||||
Ok(()) => (),
|
||||
Err(err) => {
|
||||
eprintln!("failed to flash '{}': {:X?}", path, err);
|
||||
@ -493,18 +469,15 @@ fn main() {
|
||||
},
|
||||
}
|
||||
},
|
||||
Some(("info", _sub_m)) => match unsafe { info(&mut ec) } {
|
||||
SubCommand::Info => match unsafe { info(&mut ec) } {
|
||||
Ok(()) => (),
|
||||
Err(err) => {
|
||||
eprintln!("failed to read info: {:X?}", err);
|
||||
process::exit(1);
|
||||
},
|
||||
},
|
||||
Some(("keymap", sub_m)) => {
|
||||
let layer = sub_m.value_of("layer").unwrap().parse::<u8>().unwrap();
|
||||
let output = sub_m.value_of("output").unwrap().parse::<u8>().unwrap();
|
||||
let input = sub_m.value_of("input").unwrap().parse::<u8>().unwrap();
|
||||
match sub_m.value_of("value") {
|
||||
SubCommand::Keymap { layer, output, input, value } => {
|
||||
match value {
|
||||
Some(value_str) => match u16::from_str_radix(value_str.trim_start_matches("0x"), 16) {
|
||||
Ok(value) => match unsafe { keymap_set(&mut ec, layer, output, input, value) } {
|
||||
Ok(()) => (),
|
||||
@ -527,11 +500,9 @@ fn main() {
|
||||
},
|
||||
}
|
||||
},
|
||||
Some(("led_color", sub_m)) => {
|
||||
let index = sub_m.value_of("index").unwrap().parse::<u8>().unwrap();
|
||||
let value = sub_m.value_of("value");
|
||||
SubCommand::LedColor { index, value } => {
|
||||
if let Some(value) = value {
|
||||
let (r, g, b) = parse_color(value).unwrap();
|
||||
let (r, g, b) = parse_color(&value).unwrap();
|
||||
match unsafe { ec.led_set_color(index, r, g, b) } {
|
||||
Ok(()) => (),
|
||||
Err(err) => {
|
||||
@ -549,9 +520,7 @@ fn main() {
|
||||
}
|
||||
}
|
||||
},
|
||||
Some(("led_value", sub_m)) => {
|
||||
let index = sub_m.value_of("index").unwrap().parse::<u8>().unwrap();
|
||||
let value = sub_m.value_of("value").map(|x| x.parse::<u8>().unwrap());
|
||||
SubCommand::LedValue { index, value } => {
|
||||
if let Some(value) = value {
|
||||
match unsafe { ec.led_set_value(index, value) } {
|
||||
Ok(()) => (),
|
||||
@ -573,10 +542,7 @@ fn main() {
|
||||
}
|
||||
}
|
||||
},
|
||||
Some(("led_mode", sub_m)) => {
|
||||
let layer = sub_m.value_of("layer").unwrap().parse::<u8>().unwrap();
|
||||
let mode = sub_m.value_of("mode").map(|x| x.parse::<u8>().unwrap());
|
||||
let speed = sub_m.value_of("speed").map(|x| x.parse::<u8>().unwrap());
|
||||
SubCommand::LedMode { layer, mode, speed } => {
|
||||
if let (Some(mode), Some(speed)) = (mode, speed) {
|
||||
match unsafe { ec.led_set_mode(layer, mode, speed) } {
|
||||
Ok(()) => (),
|
||||
@ -598,28 +564,28 @@ fn main() {
|
||||
}
|
||||
}
|
||||
},
|
||||
Some(("led_save", _sub_m)) => match unsafe { ec.led_save() } {
|
||||
SubCommand::LedSave => match unsafe { ec.led_save() } {
|
||||
Ok(()) => (),
|
||||
Err(err) => {
|
||||
eprintln!("failed to save LED settings: {:X?}", err);
|
||||
process::exit(1);
|
||||
},
|
||||
},
|
||||
Some(("reset", _sub_m)) => match unsafe { ec.reset() } {
|
||||
SubCommand::Reset => match unsafe { ec.reset() } {
|
||||
Ok(()) => (),
|
||||
Err(err) => {
|
||||
eprintln!("failed to reset device: {:X?}", err);
|
||||
process::exit(1);
|
||||
},
|
||||
},
|
||||
Some(("matrix", _sub_m)) => match unsafe { matrix(&mut ec) } {
|
||||
SubCommand::Matrix => match unsafe { matrix(&mut ec) } {
|
||||
Ok(()) => (),
|
||||
Err(err) => {
|
||||
eprintln!("failed to read matrix: {:X?}", err);
|
||||
process::exit(1);
|
||||
},
|
||||
},
|
||||
Some(("print", sub_m)) => for arg in sub_m.values_of("message").unwrap() {
|
||||
SubCommand::Print { message } => for arg in message {
|
||||
let mut arg = arg.to_owned();
|
||||
arg.push('\n');
|
||||
match unsafe { print(&mut ec, arg.as_bytes()) } {
|
||||
@ -630,9 +596,8 @@ fn main() {
|
||||
},
|
||||
}
|
||||
},
|
||||
Some(("set_no_input", sub_m)) => {
|
||||
let no_input = sub_m.value_of("value").unwrap().parse::<bool>().unwrap();
|
||||
match unsafe { ec.set_no_input(no_input) } {
|
||||
SubCommand::SetNoInput { value } => {
|
||||
match unsafe { ec.set_no_input(value) } {
|
||||
Ok(()) => (),
|
||||
Err(err) => {
|
||||
eprintln!("failed to set no_input mode: {:X?}", err);
|
||||
@ -640,10 +605,10 @@ fn main() {
|
||||
}
|
||||
}
|
||||
},
|
||||
Some(("security", sub_m)) => {
|
||||
match sub_m.value_of("state") {
|
||||
SubCommand::Security { state } => {
|
||||
match state {
|
||||
Some(value) => {
|
||||
let state = match value {
|
||||
let state = match value.as_str() {
|
||||
"lock" => SecurityState::PrepareLock,
|
||||
"unlock" => SecurityState::PrepareUnlock,
|
||||
_ => {
|
||||
@ -668,6 +633,5 @@ fn main() {
|
||||
},
|
||||
}
|
||||
},
|
||||
_ => unreachable!()
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user