mirror of
https://github.com/PluralKit/PluralKit.git
synced 2026-02-04 04:56:49 +00:00
fix issue with optional branches having wrong flag insert positions
This commit is contained in:
parent
e2b354aae1
commit
c5ce6fb6c0
3 changed files with 28 additions and 6 deletions
|
|
@ -1,6 +1,7 @@
|
|||
use std::{
|
||||
collections::HashSet,
|
||||
fmt::{Debug, Display},
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use smol_str::SmolStr;
|
||||
|
|
@ -17,6 +18,7 @@ pub struct Command {
|
|||
pub show_in_suggestions: bool,
|
||||
pub parse_flags_before: usize,
|
||||
pub hidden_flags: HashSet<SmolStr>,
|
||||
pub original: Option<Arc<Command>>,
|
||||
}
|
||||
|
||||
impl Command {
|
||||
|
|
@ -41,6 +43,7 @@ impl Command {
|
|||
parse_flags_before,
|
||||
tokens,
|
||||
hidden_flags: HashSet::new(),
|
||||
original: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -181,15 +181,18 @@ pub fn parse_command(
|
|||
let mut flags: HashMap<String, Option<ParameterValue>> = HashMap::new();
|
||||
let mut misplaced_flags: Vec<MatchedFlag> = Vec::new();
|
||||
let mut invalid_flags: Vec<MatchedFlag> = Vec::new();
|
||||
|
||||
for (token_idx, raw_flag) in raw_flags {
|
||||
let Some(matched_flag) = match_flag(command.flags.iter(), raw_flag.clone()) else {
|
||||
invalid_flags.push(raw_flag);
|
||||
continue;
|
||||
};
|
||||
|
||||
if token_idx != command.parse_flags_before {
|
||||
misplaced_flags.push(raw_flag);
|
||||
continue;
|
||||
}
|
||||
|
||||
match matched_flag {
|
||||
// a flag was matched
|
||||
Ok((name, value)) => {
|
||||
|
|
@ -216,6 +219,8 @@ pub fn parse_command(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
let full_cmd = command.original.as_deref().unwrap_or(&command);
|
||||
if misplaced_flags.is_empty().not() {
|
||||
let mut error = format!(
|
||||
"Flag{} ",
|
||||
|
|
@ -230,7 +235,8 @@ pub fn parse_command(
|
|||
write!(
|
||||
&mut error,
|
||||
" in command `{prefix}{input}` {} misplaced. Try reordering to match the command usage `{prefix}{command}`.",
|
||||
(misplaced_flags.len() > 1).then_some("are").unwrap_or("is")
|
||||
(misplaced_flags.len() > 1).then_some("are").unwrap_or("is"),
|
||||
command = full_cmd
|
||||
).expect("oom");
|
||||
return Err(error);
|
||||
}
|
||||
|
|
@ -250,7 +256,8 @@ pub fn parse_command(
|
|||
" {} seem to be applicable in this command (`{prefix}{command}`).",
|
||||
(invalid_flags.len() > 1)
|
||||
.then_some("don't")
|
||||
.unwrap_or("doesn't")
|
||||
.unwrap_or("doesn't"),
|
||||
command = full_cmd
|
||||
)
|
||||
.expect("oom");
|
||||
return Err(error);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use ordermap::OrderMap;
|
||||
|
||||
use crate::{command::Command, token::Token};
|
||||
|
|
@ -27,10 +29,20 @@ impl TreeBranch {
|
|||
if matches!(token, Token::Parameter(ref param) if param.is_optional())
|
||||
&& index < command.tokens.len() - 1
|
||||
{
|
||||
current_branch.register_command(Command {
|
||||
tokens: command.tokens[index + 1..].to_vec(),
|
||||
..command.clone()
|
||||
});
|
||||
let mut new_command = command.clone();
|
||||
new_command.tokens = command.tokens[index + 1..].to_vec();
|
||||
new_command.original = command
|
||||
.original
|
||||
.clone()
|
||||
.or_else(|| Some(Arc::new(command.clone())));
|
||||
|
||||
// if the optional parameter we're skipping is *before* the flag insertion point,
|
||||
// we need to shift the index left by 1 to account for the removed token
|
||||
if new_command.parse_flags_before > index {
|
||||
new_command.parse_flags_before -= 1;
|
||||
}
|
||||
|
||||
current_branch.register_command(new_command);
|
||||
}
|
||||
// recursively get or create a sub-branch for each token
|
||||
current_branch = current_branch
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue