diff --git a/crates/command_definitions/src/help.rs b/crates/command_definitions/src/help.rs index 7b206e03..d18cca3e 100644 --- a/crates/command_definitions/src/help.rs +++ b/crates/command_definitions/src/help.rs @@ -4,7 +4,7 @@ pub fn cmds() -> impl Iterator { let help = ["help", "h"]; [ command!([help] => "help") - .value_flag("foo", OpaqueString) // todo: just for testing + .flag(("foo", OpaqueString)) // todo: just for testing .help("Shows the help command"), command!([help, "commands"] => "help_commands").help("help commands"), command!([help, "proxy"] => "help_proxy").help("help proxy"), diff --git a/crates/command_parser/src/command.rs b/crates/command_parser/src/command.rs index 35bd9b10..504cab9e 100644 --- a/crates/command_parser/src/command.rs +++ b/crates/command_parser/src/command.rs @@ -2,7 +2,7 @@ use std::fmt::{Debug, Display}; use smol_str::SmolStr; -use crate::{flag::Flag, parameter::*, token::Token}; +use crate::{flag::Flag, token::Token}; #[derive(Debug, Clone)] pub struct Command { @@ -57,13 +57,8 @@ impl Command { self } - pub fn flag(mut self, name: impl Into) -> Self { - self.flags.push(Flag::new(name)); - self - } - - pub fn value_flag(mut self, name: impl Into, value: ParameterKind) -> Self { - self.flags.push(Flag::new(name).with_value(value)); + pub fn flag(mut self, flag: impl Into) -> Self { + self.flags.push(flag.into()); self } } diff --git a/crates/command_parser/src/flag.rs b/crates/command_parser/src/flag.rs index e0ff236c..11eae9b3 100644 --- a/crates/command_parser/src/flag.rs +++ b/crates/command_parser/src/flag.rs @@ -13,6 +13,7 @@ pub enum FlagValueMatchError { #[derive(Debug, Clone)] pub struct Flag { name: SmolStr, + aliases: Vec, value: Option, } @@ -38,26 +39,36 @@ impl Flag { pub fn new(name: impl Into) -> Self { Self { name: name.into(), + aliases: Vec::new(), value: None, } } - pub fn with_value(mut self, param: ParameterKind) -> Self { + pub fn value(mut self, param: ParameterKind) -> Self { self.value = Some(param); self } - pub fn name(&self) -> &str { + pub fn alias(mut self, alias: impl Into) -> Self { + self.aliases.push(alias.into()); + self + } + + pub fn get_name(&self) -> &str { &self.name } - pub fn value_kind(&self) -> Option { + pub fn get_value(&self) -> Option { self.value } + pub fn get_aliases(&self) -> impl Iterator { + self.aliases.iter().map(|s| s.as_str()) + } + pub fn try_match(&self, input_name: &str, input_value: Option<&str>) -> TryMatchFlagResult { - // if not matching flag then skip anymore matching - if self.name != input_name { + // if not matching the name or any aliases then skip anymore matching + if self.name != input_name && self.get_aliases().all(|s| s.ne(input_name)) { return None; } // get token to try matching with, if flag doesn't have one then that means it is matched (it is without any value) @@ -82,3 +93,31 @@ impl Flag { } } } + +impl From<&str> for Flag { + fn from(name: &str) -> Self { + Flag::new(name) + } +} + +impl From<(&str, ParameterKind)> for Flag { + fn from((name, value): (&str, ParameterKind)) -> Self { + Flag::new(name).value(value) + } +} + +impl From<[&str; L]> for Flag { + fn from(value: [&str; L]) -> Self { + let mut flag = Flag::new(value[0]); + for alias in &value[1..] { + flag = flag.alias(*alias); + } + flag + } +} + +impl From<([&str; L], ParameterKind)> for Flag { + fn from((names, value): ([&str; L], ParameterKind)) -> Self { + Flag::from(names).value(value) + } +} diff --git a/crates/command_parser/src/lib.rs b/crates/command_parser/src/lib.rs index d152a581..1e7c94ea 100644 --- a/crates/command_parser/src/lib.rs +++ b/crates/command_parser/src/lib.rs @@ -133,7 +133,7 @@ pub fn parse_command( FlagMatchError::ValueMatchFailed(FlagValueMatchError::ValueMissing) => { format!( "Flag `-{name}` in command `{prefix}{input}` is missing a value, try passing `{flag}`.", - name = flag.name() + name = flag.get_name() ) } FlagMatchError::ValueMatchFailed( @@ -141,7 +141,7 @@ pub fn parse_command( ) => { format!( "Flag `-{name}` in command `{prefix}{input}` has a value (`{raw}`) that could not be parsed: {msg}.", - name = flag.name() + name = flag.get_name() ) } }; @@ -210,7 +210,7 @@ fn match_flag<'a>( for flag in possible_flags { println!("matching flag {flag:?}"); match flag.try_match(matched_flag.name, matched_flag.value) { - Some(Ok(param)) => return Some(Ok((flag.name().into(), param))), + Some(Ok(param)) => return Some(Ok((flag.get_name().into(), param))), Some(Err(err)) => return Some(Err((flag, err))), None => {} }