mirror of
https://github.com/PluralKit/PluralKit.git
synced 2026-02-04 04:56:49 +00:00
use Arc throught the parser
This commit is contained in:
parent
f9367ea041
commit
c18e72450b
3 changed files with 24 additions and 20 deletions
|
|
@ -2,6 +2,8 @@
|
||||||
#![feature(round_char_boundary)]
|
#![feature(round_char_boundary)]
|
||||||
#![feature(iter_intersperse)]
|
#![feature(iter_intersperse)]
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub mod command;
|
pub mod command;
|
||||||
pub mod flag;
|
pub mod flag;
|
||||||
pub mod parameter;
|
pub mod parameter;
|
||||||
|
|
@ -28,14 +30,14 @@ pub type Tree = tree::TreeBranch;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ParsedCommand {
|
pub struct ParsedCommand {
|
||||||
pub command_def: Command,
|
pub command_def: Arc<Command>,
|
||||||
pub parameters: HashMap<String, ParameterValue>,
|
pub parameters: HashMap<String, ParameterValue>,
|
||||||
pub flags: HashMap<String, Option<ParameterValue>>,
|
pub flags: HashMap<String, Option<ParameterValue>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
struct MatchedTokenState {
|
struct MatchedTokenState {
|
||||||
tree: Tree,
|
tree: Arc<Tree>,
|
||||||
token: Token,
|
token: Token,
|
||||||
match_result: TokenMatchResult,
|
match_result: TokenMatchResult,
|
||||||
start_pos: usize,
|
start_pos: usize,
|
||||||
|
|
@ -43,12 +45,12 @@ struct MatchedTokenState {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_command(
|
pub fn parse_command(
|
||||||
command_tree: Tree,
|
command_tree: impl Into<Arc<Tree>>,
|
||||||
prefix: String,
|
prefix: String,
|
||||||
input: String,
|
input: String,
|
||||||
) -> Result<ParsedCommand, String> {
|
) -> Result<ParsedCommand, String> {
|
||||||
let input: SmolStr = input.into();
|
let input: SmolStr = input.into();
|
||||||
let mut local_tree: Tree = command_tree.clone();
|
let mut local_tree = command_tree.into();
|
||||||
|
|
||||||
// end position of all currently matched tokens
|
// end position of all currently matched tokens
|
||||||
let mut current_pos: usize = 0;
|
let mut current_pos: usize = 0;
|
||||||
|
|
@ -62,7 +64,7 @@ pub fn parse_command(
|
||||||
|
|
||||||
// track the best attempt at parsing (deepest matched tokens)
|
// track the best attempt at parsing (deepest matched tokens)
|
||||||
// so we can use it for error messages/suggestions even if we backtrack later
|
// so we can use it for error messages/suggestions even if we backtrack later
|
||||||
let mut best_attempt: Option<(Tree, Vec<MatchedTokenState>, usize)> = None;
|
let mut best_attempt: Option<(Arc<Tree>, Vec<MatchedTokenState>, usize)> = None;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut possible_tokens = local_tree
|
let mut possible_tokens = local_tree
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ use crate::{command::Command, token::Token};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct TreeBranch {
|
pub struct TreeBranch {
|
||||||
current_command: Option<Command>,
|
current_command: Option<Arc<Command>>,
|
||||||
branches: OrderMap<Token, TreeBranch>,
|
branches: OrderMap<Token, Arc<TreeBranch>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for TreeBranch {
|
impl Default for TreeBranch {
|
||||||
|
|
@ -45,16 +45,18 @@ impl TreeBranch {
|
||||||
current_branch.register_command(new_command);
|
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 = Arc::make_mut(
|
||||||
.branches
|
current_branch
|
||||||
.entry(token)
|
.branches
|
||||||
.or_insert_with(TreeBranch::default);
|
.entry(token)
|
||||||
|
.or_insert_with(|| Arc::new(TreeBranch::default())),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
// when we're out of tokens add the command to the last branch
|
// when we're out of tokens add the command to the last branch
|
||||||
current_branch.current_command = Some(command);
|
current_branch.current_command = Some(Arc::new(command));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn command(&self) -> Option<Command> {
|
pub fn command(&self) -> Option<Arc<Command>> {
|
||||||
self.current_command.clone()
|
self.current_command.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -76,7 +78,7 @@ impl TreeBranch {
|
||||||
let mut commands = box_iter(std::iter::empty());
|
let mut commands = box_iter(std::iter::empty());
|
||||||
for branch in self.branches.values() {
|
for branch in self.branches.values() {
|
||||||
if let Some(command) = branch.current_command.as_ref() {
|
if let Some(command) = branch.current_command.as_ref() {
|
||||||
commands = box_iter(commands.chain(std::iter::once(command)));
|
commands = box_iter(commands.chain(std::iter::once(command.as_ref())));
|
||||||
// we dont need to look further if we found a command
|
// we dont need to look further if we found a command
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -85,11 +87,11 @@ impl TreeBranch {
|
||||||
commands
|
commands
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_branch(&self, token: &Token) -> Option<&Self> {
|
pub fn get_branch(&self, token: &Token) -> Option<&Arc<Self>> {
|
||||||
self.branches.get(token)
|
self.branches.get(token)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn branches(&self) -> impl Iterator<Item = (&Token, &Self)> {
|
pub fn branches(&self) -> impl Iterator<Item = (&Token, &Arc<Self>)> {
|
||||||
self.branches.iter()
|
self.branches.iter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
use std::{collections::HashMap, fmt::Write};
|
use std::{collections::HashMap, fmt::Write, sync::Arc};
|
||||||
|
|
||||||
use command_parser::{parameter::ParameterValue, token::TokenMatchResult, Tree};
|
use command_parser::{parameter::ParameterValue, token::TokenMatchResult, Tree};
|
||||||
|
|
||||||
uniffi::include_scaffolding!("commands");
|
uniffi::include_scaffolding!("commands");
|
||||||
|
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
pub static ref COMMAND_TREE: Tree = {
|
pub static ref COMMAND_TREE: Arc<Tree> = {
|
||||||
let mut tree = Tree::default();
|
let mut tree = Tree::default();
|
||||||
|
|
||||||
command_definitions::all().into_iter().for_each(|x| tree.register_command(x));
|
command_definitions::all().into_iter().for_each(|x| tree.register_command(x));
|
||||||
|
|
||||||
tree
|
Arc::new(tree)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -125,7 +125,7 @@ pub fn parse_command(prefix: String, input: String) -> CommandResult {
|
||||||
|error| CommandResult::Err { error },
|
|error| CommandResult::Err { error },
|
||||||
|parsed| CommandResult::Ok {
|
|parsed| CommandResult::Ok {
|
||||||
command: {
|
command: {
|
||||||
let command_ref = parsed.command_def.cb.into();
|
let command_ref = parsed.command_def.cb.clone().into();
|
||||||
let mut flags = HashMap::with_capacity(parsed.flags.capacity());
|
let mut flags = HashMap::with_capacity(parsed.flags.capacity());
|
||||||
for (name, value) in parsed.flags {
|
for (name, value) in parsed.flags {
|
||||||
flags.insert(name, value.map(Parameter::from));
|
flags.insert(name, value.map(Parameter::from));
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue