summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Mueller <deso@posteo.net>2019-01-14 16:27:21 -0800
committerDaniel Mueller <deso@posteo.net>2019-01-14 16:27:21 -0800
commit8e0badc9988775b1b0340db5b2cb975c3ecf407d (patch)
treecc8cbbf41d09ffd2d76f5dc5c0e84727e765120c
parent4cf1b0c003a8bd0214e548a77bf0336148235931 (diff)
downloadnitrocli-8e0badc9988775b1b0340db5b2cb975c3ecf407d.tar.gz
nitrocli-8e0badc9988775b1b0340db5b2cb975c3ecf407d.tar.bz2
Auto-generate execute methods for generated command enums
Not too long ago we added a macro to auto generate the command enums and the required trait implementations from a concise declarative representation. This change extends this mechanism to the execute method implementation that some of those enums provide. When a tuple is specified as the "destination", e.g., here: > Enum! {ConfigCommand, [ > Get => ("get", config_get), > Set => ("set", config_set) > ]} the second component of this tuple will be interpreted as the function to invoke when this variant used in the newly generated execute method.
-rw-r--r--nitrocli/src/arg_util.rs23
-rw-r--r--nitrocli/src/args.rs112
2 files changed, 44 insertions, 91 deletions
diff --git a/nitrocli/src/arg_util.rs b/nitrocli/src/arg_util.rs
index 6dd14ed..b188085 100644
--- a/nitrocli/src/arg_util.rs
+++ b/nitrocli/src/arg_util.rs
@@ -22,9 +22,28 @@
// TODO: Right now we hard code the derives we create. We may want to
// make this set configurable.
macro_rules! Enum {
+ ( $name:ident, [ $( $var:ident => ($str:expr, $exec:expr) ), *] ) => {
+ Enum! {$name, [
+ $( $var => $str ),*
+ ]}
+
+ #[allow(unused_qualifications)]
+ impl $name {
+ fn execute(
+ self,
+ ctx: &mut crate::args::ExecCtx<'_>,
+ args: ::std::vec::Vec<::std::string::String>,
+ ) -> crate::Result<()> {
+ match self {
+ $(
+ $name::$var => $exec(ctx, args),
+ )*
+ }
+ }
+ }
+ };
( $name:ident, [ $( $var:ident => $str:expr ), *] ) => {
#[derive(Clone, Copy, Debug, PartialEq)]
- #[allow(unused)]
pub enum $name {
$(
$var,
@@ -59,7 +78,7 @@ macro_rules! Enum {
}
}
}
- }
+ };
}
#[cfg(test)]
diff --git a/nitrocli/src/args.rs b/nitrocli/src/args.rs
index 789001e..915186d 100644
--- a/nitrocli/src/args.rs
+++ b/nitrocli/src/args.rs
@@ -75,44 +75,20 @@ impl From<DeviceModel> for nitrokey::Model {
/// A top-level command for nitrocli.
Enum! {Command, [
- Config => "config",
- Lock => "lock",
- Otp => "otp",
- Pin => "pin",
- Pws => "pws",
- Status => "status",
- Storage => "storage"
+ Config => ("config", config),
+ Lock => ("lock", lock),
+ Otp => ("otp", otp),
+ Pin => ("pin", pin),
+ Pws => ("pws", pws),
+ Status => ("status", status),
+ Storage => ("storage", storage)
]}
-impl Command {
- /// Execute this command with the given arguments.
- pub fn execute(self, ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> {
- match self {
- Command::Config => config(ctx, args),
- Command::Lock => lock(ctx, args),
- Command::Otp => otp(ctx, args),
- Command::Pin => pin(ctx, args),
- Command::Pws => pws(ctx, args),
- Command::Status => status(ctx, args),
- Command::Storage => storage(ctx, args),
- }
- }
-}
-
Enum! {ConfigCommand, [
- Get => "get",
- Set => "set"
+ Get => ("get", config_get),
+ Set => ("set", config_set)
]}
-impl ConfigCommand {
- fn execute(self, ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> {
- match self {
- ConfigCommand::Get => config_get(ctx, args),
- ConfigCommand::Set => config_set(ctx, args),
- }
- }
-}
-
#[derive(Clone, Copy, Debug)]
pub enum ConfigOption<T> {
Enable(T),
@@ -149,23 +125,12 @@ impl<T> ConfigOption<T> {
}
Enum! {OtpCommand, [
- Clear => "clear",
- Get => "get",
- Set => "set",
- Status => "status"
+ Clear => ("clear", otp_clear),
+ Get => ("get", otp_get),
+ Set => ("set", otp_set),
+ Status => ("status", otp_status)
]}
-impl OtpCommand {
- fn execute(self, ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> {
- match self {
- OtpCommand::Clear => otp_clear(ctx, args),
- OtpCommand::Get => otp_get(ctx, args),
- OtpCommand::Set => otp_set(ctx, args),
- OtpCommand::Status => otp_status(ctx, args),
- }
- }
-}
-
Enum! {OtpAlgorithm, [
Hotp => "hotp",
Totp => "totp"
@@ -192,39 +157,18 @@ Enum! {OtpSecretFormat, [
]}
Enum! {PinCommand, [
- Clear => "clear",
- Set => "set",
- Unblock => "unblock"
+ Clear => ("clear", pin_clear),
+ Set => ("set", pin_set),
+ Unblock => ("unblock", pin_unblock)
]}
-impl PinCommand {
- fn execute(self, ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> {
- match self {
- PinCommand::Clear => pin_clear(ctx, args),
- PinCommand::Set => pin_set(ctx, args),
- PinCommand::Unblock => pin_unblock(ctx, args),
- }
- }
-}
-
Enum! {PwsCommand, [
- Clear => "clear",
- Get => "get",
- Set => "set",
- Status => "status"
+ Clear => ("clear", pws_clear),
+ Get => ("get", pws_get),
+ Set => ("set", pws_set),
+ Status => ("status", pws_status)
]}
-impl PwsCommand {
- fn execute(self, ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> {
- match self {
- PwsCommand::Clear => pws_clear(ctx, args),
- PwsCommand::Get => pws_get(ctx, args),
- PwsCommand::Set => pws_set(ctx, args),
- PwsCommand::Status => pws_status(ctx, args),
- }
- }
-}
-
fn parse(
ctx: &mut impl Stdio,
parser: &argparse::ArgumentParser<'_>,
@@ -248,21 +192,11 @@ fn status(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> {
}
Enum! {StorageCommand, [
- Close => "close",
- Open => "open",
- Status => "status"
+ Close => ("close", storage_close),
+ Open => ("open", storage_open),
+ Status => ("status", storage_status)
]}
-impl StorageCommand {
- fn execute(self, ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> {
- match self {
- StorageCommand::Close => storage_close(ctx, args),
- StorageCommand::Open => storage_open(ctx, args),
- StorageCommand::Status => storage_status(ctx, args),
- }
- }
-}
-
/// Execute a storage subcommand.
fn storage(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> {
let mut subcommand = StorageCommand::Open;