From 8ead3c106b932fad81cc6e9993774a226f739179 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Fri, 8 May 2026 15:49:13 +0800 Subject: Dispatch arguments using prefix tree with dispatch_tree feature --- mingling_core/src/asset/comp.rs | 35 ++++++++++++++++++++++++++++++----- mingling_core/src/program.rs | 15 ++++++++++++++- 2 files changed, 44 insertions(+), 6 deletions(-) (limited to 'mingling_core/src') diff --git a/mingling_core/src/asset/comp.rs b/mingling_core/src/asset/comp.rs index cf1f48c..4fb17c7 100644 --- a/mingling_core/src/asset/comp.rs +++ b/mingling_core/src/asset/comp.rs @@ -12,7 +12,10 @@ pub use shell_ctx::*; #[doc(hidden)] pub use suggest::*; -use crate::{ProgramCollect, debug, exec::match_user_input, only_debug, this, trace}; +use crate::{ProgramCollect, debug, only_debug, this, trace}; + +#[cfg(not(feature = "dispatch_tree"))] +use crate::exec::match_user_input; /// Trait for implementing completion logic. /// @@ -42,20 +45,24 @@ pub struct CompletionHelper; impl CompletionHelper { pub fn exec_completion

(ctx: &ShellContext) -> Suggest where - P: ProgramCollect + Display + 'static, + P: ProgramCollect + Display + PartialEq + 'static, { only_debug! { crate::debug::init_env_logger(); trace_ctx(ctx); }; - let program = this::

(); let args = ctx.all_words.iter().skip(1).cloned().collect::>(); + trace!("arguments=\"{}\"", args.join(", ")); + + #[cfg(not(feature = "dispatch_tree"))] + let program = this::

(); + + #[cfg(not(feature = "dispatch_tree"))] let suggest = if let Ok((dispatcher, args)) = match_user_input(program, &args) { trace!( - "dispatcher matched, dispatcher=\"{}\", args={:?}", + "dispatcher matched, dispatcher=\"{}\"", dispatcher.node().to_string(), - args ); let begin = dispatcher.begin(args); if let crate::ChainProcess::Ok((any, _)) = begin { @@ -71,6 +78,24 @@ impl CompletionHelper { trace!("no dispatcher matched"); None }; + #[cfg(feature = "dispatch_tree")] + let suggest = if let Ok(any) = P::dispatch_args_trie(&args) { + trace!("entry type: {}", any.member_id); + + let dispatcher_not_found = >::member_id(); + + if dispatcher_not_found == any.member_id { + trace!("begin not Ok"); + None + } else { + let result = P::do_comp(&any, ctx); + trace!("do_comp result: {:?}", result); + Some(result) + } + } else { + trace!("no dispatcher matched"); + None + }; match suggest { Some(suggest) => { diff --git a/mingling_core/src/program.rs b/mingling_core/src/program.rs index c7544f5..f305e88 100644 --- a/mingling_core/src/program.rs +++ b/mingling_core/src/program.rs @@ -8,7 +8,7 @@ use crate::error::GeneralRendererSerializeError; use std::env; use crate::{ - AnyOutput, ChainProcess, GlobalResources, RenderResult, + AnyOutput, ChainProcess, GlobalResources, Groupped, RenderResult, asset::dispatcher::Dispatcher, error::{ChainProcessError, ProgramExecuteError}, }; @@ -148,6 +148,19 @@ where Err(e) => Err(e.into()), } } + + /// Use a prefix tree to quickly match arguments and dispatch to an Entry + #[cfg(feature = "dispatch_tree")] + pub fn dispatch_args_trie( + &'static self, + args: impl Into, + ) -> Result, ChainProcessError> { + let string_vec: Vec = args.into().into(); + match C::dispatch_args_trie(&string_vec) { + Ok(ok) => Ok(ok), + Err(e) => Err(e.into()), + } + } } // Async program -- cgit