diff options
Diffstat (limited to 'mingling_core/src')
| -rw-r--r-- | mingling_core/src/asset/comp.rs | 2 | ||||
| -rw-r--r-- | mingling_core/src/asset/dispatcher.rs | 2 | ||||
| -rw-r--r-- | mingling_core/src/program.rs | 38 | ||||
| -rw-r--r-- | mingling_core/src/program/exec.rs | 30 |
4 files changed, 55 insertions, 17 deletions
diff --git a/mingling_core/src/asset/comp.rs b/mingling_core/src/asset/comp.rs index a6299e1..cf1f48c 100644 --- a/mingling_core/src/asset/comp.rs +++ b/mingling_core/src/asset/comp.rs @@ -51,7 +51,7 @@ impl CompletionHelper { let program = this::<P>(); let args = ctx.all_words.iter().skip(1).cloned().collect::<Vec<_>>(); - let suggest = if let Ok((dispatcher, args)) = match_user_input(program, args) { + let suggest = if let Ok((dispatcher, args)) = match_user_input(program, &args) { trace!( "dispatcher matched, dispatcher=\"{}\", args={:?}", dispatcher.node().to_string(), diff --git a/mingling_core/src/asset/dispatcher.rs b/mingling_core/src/asset/dispatcher.rs index 761c399..cf8fcca 100644 --- a/mingling_core/src/asset/dispatcher.rs +++ b/mingling_core/src/asset/dispatcher.rs @@ -29,6 +29,7 @@ where impl<C: crate::program::ProgramCollect> Program<C> { /// Adds a dispatcher to the program. + #[cfg(not(feature = "dispatch_tree"))] pub fn with_dispatcher<Disp>(&mut self, dispatcher: Disp) where Disp: Dispatcher<C> + Send + Sync + 'static, @@ -37,6 +38,7 @@ impl<C: crate::program::ProgramCollect> Program<C> { } /// Add some dispatchers to the program. + #[cfg(not(feature = "dispatch_tree"))] pub fn with_dispatchers<D>(&mut self, dispatchers: D) where D: Into<Dispatchers<C>>, diff --git a/mingling_core/src/program.rs b/mingling_core/src/program.rs index 1505480..df5b285 100644 --- a/mingling_core/src/program.rs +++ b/mingling_core/src/program.rs @@ -63,6 +63,8 @@ where pub(crate) collect: std::marker::PhantomData<C>, pub(crate) args: Vec<String>, + + #[cfg(not(feature = "dispatch_tree"))] pub(crate) dispatcher: Vec<Box<dyn Dispatcher<C> + Send + Sync>>, pub stdout_setting: ProgramStdoutSetting, @@ -101,12 +103,16 @@ where Program { collect: std::marker::PhantomData, args: args.into().into(), + + #[cfg(not(feature = "dispatch_tree"))] dispatcher: Vec::new(), + stdout_setting: Default::default(), user_context: Default::default(), #[cfg(feature = "general_renderer")] general_renderer_name: GeneralRendererSetting::Disable, + resources: Arc::new(Mutex::new(HashMap::new())), } } @@ -126,16 +132,18 @@ where } /// Get all registered dispatcher names from the program - pub fn get_nodes(&self) -> Vec<(String, &(dyn Dispatcher<C> + Send + Sync))> { + pub fn get_nodes( + &'static self, + ) -> Vec<(String, &'static (dyn Dispatcher<C> + Send + Sync + 'static))> { get_nodes(self) } /// Dynamically dispatch input arguments to registered entry types pub fn dispatch_args_dynamic( - &self, + &'static self, args: impl Into<StringVec>, ) -> Result<AnyOutput<C>, ChainProcessError> { - match exec::dispatch_args_dynamic(self, args.into().into()) { + match exec::dispatch_args_dynamic(self, &args.into().into()) { Ok(ok) => Ok(ok), Err(e) => Err(e.into()), } @@ -287,6 +295,16 @@ pub trait ProgramCollect { /// Enum type representing internal IDs for the program type Enum: Display; + /// Use a prefix tree to quickly match arguments and dispatch to an Entry + #[cfg(feature = "dispatch_tree")] + fn dispatch_args_trie( + raw: &Vec<String>, + ) -> Result<AnyOutput<Self::Enum>, crate::error::ProgramInternalExecuteError>; + + /// Get all registered dispatcher names from the program + #[cfg(feature = "dispatch_tree")] + fn get_nodes() -> Vec<(String, &'static (dyn Dispatcher<Self::Enum> + Send + Sync))>; + /// Build an [AnyOutput](./struct.AnyOutput.html) to indicate that a renderer was not found fn build_renderer_not_found(member_id: Self::Enum) -> AnyOutput<Self::Enum>; @@ -402,9 +420,13 @@ macro_rules! __dispatch_program_chains { /// Get all registered dispatcher names from the program pub fn get_nodes<C: ProgramCollect<Enum = C>>( - program: &Program<C>, -) -> Vec<(String, &(dyn Dispatcher<C> + Send + Sync))> { - program + program: &'static Program<C>, +) -> Vec<(String, &'static (dyn Dispatcher<C> + Send + Sync + 'static))> { + #[cfg(feature = "dispatch_tree")] + let r = C::get_nodes(); + + #[cfg(not(feature = "dispatch_tree"))] + let r = program .dispatcher .iter() .map(|disp| { @@ -416,5 +438,7 @@ pub fn get_nodes<C: ProgramCollect<Enum = C>>( .join(" "); (node_str, &**disp) }) - .collect() + .collect(); + + return r; } diff --git a/mingling_core/src/program/exec.rs b/mingling_core/src/program/exec.rs index 469f6d2..9cb2892 100644 --- a/mingling_core/src/program/exec.rs +++ b/mingling_core/src/program/exec.rs @@ -9,11 +9,18 @@ use crate::{ pub mod error; #[cfg(feature = "async")] -pub async fn exec<C>(program: &Program<C>) -> Result<RenderResult, ProgramInternalExecuteError> +pub async fn exec<C>( + program: &'static Program<C>, +) -> Result<RenderResult, ProgramInternalExecuteError> where C: ProgramCollect<Enum = C>, { - let mut current = dispatch_args_dynamic(program, program.args.clone())?; + #[cfg(not(feature = "dispatch_tree"))] + let mut current = dispatch_args_dynamic(program, &program.args)?; + + #[cfg(feature = "dispatch_tree")] + let mut current = C::dispatch_args_trie(&program.args)?; + let mut stop_next = false; // If the program has Help enabled, skip actual logic and jump to Help @@ -54,11 +61,16 @@ where } #[cfg(not(feature = "async"))] -pub fn exec<C>(program: &Program<C>) -> Result<RenderResult, ProgramInternalExecuteError> +pub fn exec<C>(program: &'static Program<C>) -> Result<RenderResult, ProgramInternalExecuteError> where C: ProgramCollect<Enum = C>, { - let mut current = dispatch_args_dynamic(program, program.args.clone())?; + #[cfg(not(feature = "dispatch_tree"))] + let mut current = dispatch_args_dynamic(program, &program.args)?; + + #[cfg(feature = "dispatch_tree")] + let mut current = C::dispatch_args_trie(&program.args)?; + let mut stop_next = false; // If the program has Help enabled, skip actual logic and jump to Help @@ -100,8 +112,8 @@ where /// Dynamically dispatch input arguments to registered entry types pub(crate) fn dispatch_args_dynamic<C>( - program: &Program<C>, - args: Vec<String>, + program: &'static Program<C>, + args: &Vec<String>, ) -> Result<AnyOutput<C>, ProgramInternalExecuteError> where C: ProgramCollect<Enum = C>, @@ -126,9 +138,9 @@ where /// Match user input against registered dispatchers and return the matched dispatcher and remaining arguments. #[allow(clippy::type_complexity)] pub(crate) fn match_user_input<C>( - program: &Program<C>, - args: Vec<String>, -) -> Result<(&(dyn Dispatcher<C> + Send + Sync), Vec<String>), ProgramInternalExecuteError> + program: &'static Program<C>, + args: &Vec<String>, +) -> Result<(&'static (dyn Dispatcher<C> + Send + Sync), Vec<String>), ProgramInternalExecuteError> where C: ProgramCollect<Enum = C>, { |
