mirror of
https://github.com/PluralKit/PluralKit.git
synced 2026-02-04 13:06:50 +00:00
feat(command_parser): allow aliases in flags
This commit is contained in:
parent
bf5e448aad
commit
ff6dc12cae
4 changed files with 51 additions and 17 deletions
|
|
@ -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<SmolStr>) -> Self {
|
||||
self.flags.push(Flag::new(name));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn value_flag(mut self, name: impl Into<SmolStr>, value: ParameterKind) -> Self {
|
||||
self.flags.push(Flag::new(name).with_value(value));
|
||||
pub fn flag(mut self, flag: impl Into<Flag>) -> Self {
|
||||
self.flags.push(flag.into());
|
||||
self
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ pub enum FlagValueMatchError {
|
|||
#[derive(Debug, Clone)]
|
||||
pub struct Flag {
|
||||
name: SmolStr,
|
||||
aliases: Vec<SmolStr>,
|
||||
value: Option<ParameterKind>,
|
||||
}
|
||||
|
||||
|
|
@ -38,26 +39,36 @@ impl Flag {
|
|||
pub fn new(name: impl Into<SmolStr>) -> 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<SmolStr>) -> Self {
|
||||
self.aliases.push(alias.into());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn get_name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
|
||||
pub fn value_kind(&self) -> Option<ParameterKind> {
|
||||
pub fn get_value(&self) -> Option<ParameterKind> {
|
||||
self.value
|
||||
}
|
||||
|
||||
pub fn get_aliases(&self) -> impl Iterator<Item = &str> {
|
||||
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<const L: usize> 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<const L: usize> From<([&str; L], ParameterKind)> for Flag {
|
||||
fn from((names, value): ([&str; L], ParameterKind)) -> Self {
|
||||
Flag::from(names).value(value)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 => {}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue