aboutsummaryrefslogtreecommitdiff
path: root/mingling_core/src
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-05-08 15:49:13 +0800
committer魏曹先生 <1992414357@qq.com>2026-05-08 15:49:13 +0800
commit8ead3c106b932fad81cc6e9993774a226f739179 (patch)
treed4d0a1c3e0cb8e66fb0316209c8006ba379bd8aa /mingling_core/src
parentb47bdc15fdb78ac5e78b2e04aca0190c84aa78f4 (diff)
Dispatch arguments using prefix tree with dispatch_tree feature
Diffstat (limited to 'mingling_core/src')
-rw-r--r--mingling_core/src/asset/comp.rs35
-rw-r--r--mingling_core/src/program.rs15
2 files changed, 44 insertions, 6 deletions
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<P>(ctx: &ShellContext) -> Suggest
where
- P: ProgramCollect<Enum = P> + Display + 'static,
+ P: ProgramCollect<Enum = P> + Display + PartialEq + 'static,
{
only_debug! {
crate::debug::init_env_logger();
trace_ctx(ctx);
};
- let program = this::<P>();
let args = ctx.all_words.iter().skip(1).cloned().collect::<Vec<_>>();
+ trace!("arguments=\"{}\"", args.join(", "));
+
+ #[cfg(not(feature = "dispatch_tree"))]
+ let program = this::<P>();
+
+ #[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 = <P::DispatcherNotFound as crate::Groupped<P>>::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<StringVec>,
+ ) -> Result<AnyOutput<C>, ChainProcessError> {
+ let string_vec: Vec<String> = args.into().into();
+ match C::dispatch_args_trie(&string_vec) {
+ Ok(ok) => Ok(ok),
+ Err(e) => Err(e.into()),
+ }
+ }
}
// Async program