2025-01-05 13:00:06 +09:00
|
|
|
use ordermap::OrderMap;
|
2025-01-04 07:43:55 +09:00
|
|
|
|
2025-01-21 04:31:03 +09:00
|
|
|
use crate::{command::Command, token::Token};
|
2025-01-04 07:35:04 +09:00
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
|
pub struct TreeBranch {
|
2025-01-11 22:38:29 +09:00
|
|
|
current_command: Option<Command>,
|
2025-01-11 20:25:41 +09:00
|
|
|
branches: OrderMap<Token, TreeBranch>,
|
2025-01-04 07:35:04 +09:00
|
|
|
}
|
|
|
|
|
|
2025-01-21 04:31:03 +09:00
|
|
|
impl Default for TreeBranch {
|
|
|
|
|
fn default() -> Self {
|
2025-01-11 19:51:45 +09:00
|
|
|
Self {
|
2025-01-11 22:38:29 +09:00
|
|
|
current_command: None,
|
2025-01-11 19:51:45 +09:00
|
|
|
branches: OrderMap::new(),
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-01-21 04:31:03 +09:00
|
|
|
}
|
2025-01-11 19:51:45 +09:00
|
|
|
|
2025-01-21 04:31:03 +09:00
|
|
|
impl TreeBranch {
|
2025-01-04 07:35:04 +09:00
|
|
|
pub fn register_command(&mut self, command: Command) {
|
|
|
|
|
let mut current_branch = self;
|
|
|
|
|
// iterate over tokens in command
|
2025-01-11 22:38:29 +09:00
|
|
|
for token in command.tokens.clone() {
|
2025-01-04 07:35:04 +09:00
|
|
|
// recursively get or create a sub-branch for each token
|
2025-01-14 11:53:56 +09:00
|
|
|
current_branch = current_branch
|
|
|
|
|
.branches
|
|
|
|
|
.entry(token)
|
2025-01-21 04:31:03 +09:00
|
|
|
.or_insert_with(TreeBranch::default);
|
2025-01-04 07:35:04 +09:00
|
|
|
}
|
|
|
|
|
// when we're out of tokens, add an Empty branch with the callback and no sub-branches
|
|
|
|
|
current_branch.branches.insert(
|
|
|
|
|
Token::Empty,
|
|
|
|
|
TreeBranch {
|
2025-01-05 13:00:06 +09:00
|
|
|
branches: OrderMap::new(),
|
2025-01-14 11:53:56 +09:00
|
|
|
current_command: Some(command),
|
2025-01-04 07:35:04 +09:00
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
2025-01-11 20:25:41 +09:00
|
|
|
|
2025-01-21 04:31:03 +09:00
|
|
|
pub(super) fn command(&self) -> Option<Command> {
|
2025-01-11 22:38:29 +09:00
|
|
|
self.current_command.clone()
|
2025-01-11 20:25:41 +09:00
|
|
|
}
|
|
|
|
|
|
2025-01-21 04:31:03 +09:00
|
|
|
pub(super) fn possible_tokens(&self) -> impl Iterator<Item = &Token> {
|
2025-01-11 20:25:41 +09:00
|
|
|
self.branches.keys()
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-21 04:31:03 +09:00
|
|
|
pub(super) fn possible_commands(&self, max_depth: usize) -> impl Iterator<Item = &Command> {
|
2025-01-12 04:23:46 +09:00
|
|
|
// dusk: i am too lazy to write an iterator for this without using recursion so we box everything
|
|
|
|
|
fn box_iter<'a>(
|
|
|
|
|
iter: impl Iterator<Item = &'a Command> + 'a,
|
|
|
|
|
) -> Box<dyn Iterator<Item = &'a Command> + 'a> {
|
|
|
|
|
Box::new(iter)
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-11 22:38:29 +09:00
|
|
|
if max_depth == 0 {
|
2025-01-12 04:23:46 +09:00
|
|
|
return box_iter(std::iter::empty());
|
2025-01-11 22:38:29 +09:00
|
|
|
}
|
2025-01-12 04:23:46 +09:00
|
|
|
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)));
|
|
|
|
|
// we dont need to look further if we found a command (only Empty tokens have commands)
|
|
|
|
|
continue;
|
2025-01-11 22:38:29 +09:00
|
|
|
}
|
2025-01-12 04:23:46 +09:00
|
|
|
commands = box_iter(commands.chain(branch.possible_commands(max_depth - 1)));
|
2025-01-11 22:38:29 +09:00
|
|
|
}
|
|
|
|
|
commands
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-21 04:31:03 +09:00
|
|
|
pub(super) fn get_branch(&self, token: &Token) -> Option<&TreeBranch> {
|
2025-01-11 20:25:41 +09:00
|
|
|
self.branches.get(token)
|
|
|
|
|
}
|
2025-01-04 07:35:04 +09:00
|
|
|
}
|