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::{
|
use std::{
|
||||||
collections::HashSet,
|
collections::HashSet,
|
||||||
fmt::{Debug, Display},
|
fmt::{Debug, Display},
|
||||||
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
use smol_str::SmolStr;
|
use smol_str::SmolStr;
|
||||||
|
|
@ -17,6 +18,7 @@ pub struct Command {
|
||||||
pub show_in_suggestions: bool,
|
pub show_in_suggestions: bool,
|
||||||
pub parse_flags_before: usize,
|
pub parse_flags_before: usize,
|
||||||
pub hidden_flags: HashSet<SmolStr>,
|
pub hidden_flags: HashSet<SmolStr>,
|
||||||
|
pub original: Option<Arc<Command>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Command {
|
impl Command {
|
||||||
|
|
@ -41,6 +43,7 @@ impl Command {
|
||||||
parse_flags_before,
|
parse_flags_before,
|
||||||
tokens,
|
tokens,
|
||||||
hidden_flags: HashSet::new(),
|
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 flags: HashMap<String, Option<ParameterValue>> = HashMap::new();
|
||||||
let mut misplaced_flags: Vec<MatchedFlag> = Vec::new();
|
let mut misplaced_flags: Vec<MatchedFlag> = Vec::new();
|
||||||
let mut invalid_flags: Vec<MatchedFlag> = Vec::new();
|
let mut invalid_flags: Vec<MatchedFlag> = Vec::new();
|
||||||
|
|
||||||
for (token_idx, raw_flag) in raw_flags {
|
for (token_idx, raw_flag) in raw_flags {
|
||||||
let Some(matched_flag) = match_flag(command.flags.iter(), raw_flag.clone()) else {
|
let Some(matched_flag) = match_flag(command.flags.iter(), raw_flag.clone()) else {
|
||||||
invalid_flags.push(raw_flag);
|
invalid_flags.push(raw_flag);
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
if token_idx != command.parse_flags_before {
|
if token_idx != command.parse_flags_before {
|
||||||
misplaced_flags.push(raw_flag);
|
misplaced_flags.push(raw_flag);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
match matched_flag {
|
match matched_flag {
|
||||||
// a flag was matched
|
// a flag was matched
|
||||||
Ok((name, value)) => {
|
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() {
|
if misplaced_flags.is_empty().not() {
|
||||||
let mut error = format!(
|
let mut error = format!(
|
||||||
"Flag{} ",
|
"Flag{} ",
|
||||||
|
|
@ -230,7 +235,8 @@ pub fn parse_command(
|
||||||
write!(
|
write!(
|
||||||
&mut error,
|
&mut error,
|
||||||
" in command `{prefix}{input}` {} misplaced. Try reordering to match the command usage `{prefix}{command}`.",
|
" 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");
|
).expect("oom");
|
||||||
return Err(error);
|
return Err(error);
|
||||||
}
|
}
|
||||||
|
|
@ -250,7 +256,8 @@ pub fn parse_command(
|
||||||
" {} seem to be applicable in this command (`{prefix}{command}`).",
|
" {} seem to be applicable in this command (`{prefix}{command}`).",
|
||||||
(invalid_flags.len() > 1)
|
(invalid_flags.len() > 1)
|
||||||
.then_some("don't")
|
.then_some("don't")
|
||||||
.unwrap_or("doesn't")
|
.unwrap_or("doesn't"),
|
||||||
|
command = full_cmd
|
||||||
)
|
)
|
||||||
.expect("oom");
|
.expect("oom");
|
||||||
return Err(error);
|
return Err(error);
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use ordermap::OrderMap;
|
use ordermap::OrderMap;
|
||||||
|
|
||||||
use crate::{command::Command, token::Token};
|
use crate::{command::Command, token::Token};
|
||||||
|
|
@ -27,10 +29,20 @@ impl TreeBranch {
|
||||||
if matches!(token, Token::Parameter(ref param) if param.is_optional())
|
if matches!(token, Token::Parameter(ref param) if param.is_optional())
|
||||||
&& index < command.tokens.len() - 1
|
&& index < command.tokens.len() - 1
|
||||||
{
|
{
|
||||||
current_branch.register_command(Command {
|
let mut new_command = command.clone();
|
||||||
tokens: command.tokens[index + 1..].to_vec(),
|
new_command.tokens = command.tokens[index + 1..].to_vec();
|
||||||
..command.clone()
|
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
|
// recursively get or create a sub-branch for each token
|
||||||
current_branch = current_branch
|
current_branch = current_branch
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue