use Arc throught the parser

This commit is contained in:
dawn 2026-01-19 17:57:50 +03:00
parent f9367ea041
commit c18e72450b
No known key found for this signature in database
3 changed files with 24 additions and 20 deletions

View file

@ -2,6 +2,8 @@
#![feature(round_char_boundary)]
#![feature(iter_intersperse)]
use std::sync::Arc;
pub mod command;
pub mod flag;
pub mod parameter;
@ -28,14 +30,14 @@ pub type Tree = tree::TreeBranch;
#[derive(Debug)]
pub struct ParsedCommand {
pub command_def: Command,
pub command_def: Arc<Command>,
pub parameters: HashMap<String, ParameterValue>,
pub flags: HashMap<String, Option<ParameterValue>>,
}
#[derive(Clone, Debug)]
struct MatchedTokenState {
tree: Tree,
tree: Arc<Tree>,
token: Token,
match_result: TokenMatchResult,
start_pos: usize,
@ -43,12 +45,12 @@ struct MatchedTokenState {
}
pub fn parse_command(
command_tree: Tree,
command_tree: impl Into<Arc<Tree>>,
prefix: String,
input: String,
) -> Result<ParsedCommand, String> {
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
let mut current_pos: usize = 0;
@ -62,7 +64,7 @@ pub fn parse_command(
// track the best attempt at parsing (deepest matched tokens)
// 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 {
let mut possible_tokens = local_tree

View file

@ -6,8 +6,8 @@ use crate::{command::Command, token::Token};
#[derive(Debug, Clone)]
pub struct TreeBranch {
current_command: Option<Command>,
branches: OrderMap<Token, TreeBranch>,
current_command: Option<Arc<Command>>,
branches: OrderMap<Token, Arc<TreeBranch>>,
}
impl Default for TreeBranch {
@ -45,16 +45,18 @@ impl TreeBranch {
current_branch.register_command(new_command);
}
// recursively get or create a sub-branch for each token
current_branch = current_branch
.branches
.entry(token)
.or_insert_with(TreeBranch::default);
current_branch = Arc::make_mut(
current_branch
.branches
.entry(token)
.or_insert_with(|| Arc::new(TreeBranch::default())),
);
}
// 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()
}
@ -76,7 +78,7 @@ impl TreeBranch {
let mut commands = box_iter(std::iter::empty());
for branch in self.branches.values() {
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
continue;
}
@ -85,11 +87,11 @@ impl TreeBranch {
commands
}
pub fn get_branch(&self, token: &Token) -> Option<&Self> {
pub fn get_branch(&self, token: &Token) -> Option<&Arc<Self>> {
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()
}
}