diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-04-22 13:27:43 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-04-22 13:30:13 +0800 |
| commit | 3785202ec5b949cba5501b20729b16f4c29ea626 (patch) | |
| tree | 2a276df54128e73557463af54d626a1a7c250e94 /mingling_core/src/program | |
| parent | c2f9fb47832c5e12fe37762616c81b016de00464 (diff) | |
Add new_with_args and dispatch_args_dynamic to Program
Remove Display bound from Group type parameter and delete
dispatcher_render macro. This is a breaking change.
Diffstat (limited to 'mingling_core/src/program')
| -rw-r--r-- | mingling_core/src/program/exec.rs | 76 | ||||
| -rw-r--r-- | mingling_core/src/program/setup.rs | 4 | ||||
| -rw-r--r-- | mingling_core/src/program/string_vec.rs | 56 |
3 files changed, 85 insertions, 51 deletions
diff --git a/mingling_core/src/program/exec.rs b/mingling_core/src/program/exec.rs index 8ab2036..68a694e 100644 --- a/mingling_core/src/program/exec.rs +++ b/mingling_core/src/program/exec.rs @@ -1,7 +1,5 @@ #![allow(clippy::borrowed_box)] -use std::fmt::Display; - use crate::{ AnyOutput, ChainProcess, Dispatcher, Next, Program, ProgramCollect, RenderResult, error::ProgramInternalExecuteError, @@ -16,30 +14,10 @@ pub async fn exec<C, G>( ) -> Result<RenderResult, ProgramInternalExecuteError> where C: ProgramCollect<Enum = G>, - G: Display, { - let mut current; + let mut current = dispatch_args_dynamic(program, program.args.clone())?; let mut stop_next = false; - // Match user input - match match_user_input(program, program.args.clone()) { - Ok((dispatcher, args)) => { - // Entry point - current = match dispatcher.begin(args) { - ChainProcess::Ok((any, Next::Renderer)) => { - return Ok(render::<C, G>(program, any)); - } - ChainProcess::Ok((any, Next::Chain)) => any, - ChainProcess::Err(e) => return Err(e.into()), - }; - } - Err(ProgramInternalExecuteError::DispatcherNotFound) => { - // No matching Dispatcher is found - current = C::build_dispatcher_not_found(program.args.clone()); - } - Err(e) => return Err(e), - }; - loop { let final_exec = stop_next; @@ -76,30 +54,10 @@ where pub fn exec<C, G>(program: &Program<C, G>) -> Result<RenderResult, ProgramInternalExecuteError> where C: ProgramCollect<Enum = G>, - G: Display, { - let mut current; + let mut current = dispatch_args_dynamic(program, program.args.clone())?; let mut stop_next = false; - // Match user input - match match_user_input(program, program.args.clone()) { - Ok((dispatcher, args)) => { - // Entry point - current = match dispatcher.begin(args) { - ChainProcess::Ok((any, Next::Renderer)) => { - return Ok(render::<C, G>(program, any)); - } - ChainProcess::Ok((any, Next::Chain)) => any, - ChainProcess::Err(e) => return Err(e.into()), - }; - } - Err(ProgramInternalExecuteError::DispatcherNotFound) => { - // No matching Dispatcher is found - current = C::build_dispatcher_not_found(program.args.clone()); - } - Err(e) => return Err(e), - }; - loop { let final_exec = stop_next; @@ -132,15 +90,39 @@ where Ok(RenderResult::default()) } +/// Dynamically dispatch input arguments to registered entry types +pub(crate) fn dispatch_args_dynamic<C, G>( + program: &Program<C, G>, + args: Vec<String>, +) -> Result<AnyOutput<G>, ProgramInternalExecuteError> +where + C: ProgramCollect<Enum = G>, +{ + let next = match match_user_input(program, args) { + Ok((dispatcher, args)) => { + // Entry point + match dispatcher.begin(args) { + ChainProcess::Ok((any, _)) => any, + ChainProcess::Err(e) => return Err(e.into()), + } + } + Err(ProgramInternalExecuteError::DispatcherNotFound) => { + // No matching Dispatcher is found + C::build_dispatcher_not_found(program.args.clone()) + } + Err(e) => return Err(e), + }; + Ok(next) +} + /// Match user input against registered dispatchers and return the matched dispatcher and remaining arguments. #[allow(clippy::type_complexity)] -pub fn match_user_input<C, G>( +pub(crate) fn match_user_input<C, G>( program: &Program<C, G>, args: Vec<String>, ) -> Result<(&(dyn Dispatcher<G> + Send + Sync), Vec<String>), ProgramInternalExecuteError> where C: ProgramCollect<Enum = G>, - G: Display, { let nodes = program.get_nodes(); let command = format!("{} ", args.join(" ")); @@ -180,7 +162,7 @@ where #[inline(always)] #[allow(unused_variables)] -fn render<C: ProgramCollect<Enum = G>, G: Display>( +fn render<C: ProgramCollect<Enum = G>, G>( program: &Program<C, G>, any: AnyOutput<G>, ) -> RenderResult { diff --git a/mingling_core/src/program/setup.rs b/mingling_core/src/program/setup.rs index 7b534f3..f095ed3 100644 --- a/mingling_core/src/program/setup.rs +++ b/mingling_core/src/program/setup.rs @@ -1,5 +1,3 @@ -use std::fmt::Display; - use crate::{ProgramCollect, program::Program}; mod basic; @@ -13,7 +11,6 @@ pub use general_renderer::*; pub trait ProgramSetup<C, G> where C: ProgramCollect, - G: Display, { fn setup(&mut self, program: &mut Program<C, G>); } @@ -21,7 +18,6 @@ where impl<C, G> Program<C, G> where C: ProgramCollect, - G: Display, { /// Load and execute init logic pub fn with_setup<S: ProgramSetup<C, G> + 'static>(&mut self, mut setup: S) -> S { diff --git a/mingling_core/src/program/string_vec.rs b/mingling_core/src/program/string_vec.rs new file mode 100644 index 0000000..478ad74 --- /dev/null +++ b/mingling_core/src/program/string_vec.rs @@ -0,0 +1,56 @@ +#[derive(Debug, Clone)] +pub struct StringVec { + vec: Vec<String>, +} + +impl std::ops::Deref for StringVec { + type Target = Vec<String>; + + fn deref(&self) -> &Self::Target { + &self.vec + } +} + +impl From<StringVec> for Vec<String> { + fn from(val: StringVec) -> Self { + val.vec + } +} + +impl<const N: usize> From<[&str; N]> for StringVec { + fn from(slice: [&str; N]) -> Self { + StringVec { + vec: slice.iter().map(|&s| s.to_string()).collect(), + } + } +} + +impl From<&[&str]> for StringVec { + fn from(slice: &[&str]) -> Self { + StringVec { + vec: slice.iter().map(|&s| s.to_string()).collect(), + } + } +} + +impl From<Vec<String>> for StringVec { + fn from(vec: Vec<String>) -> Self { + StringVec { vec } + } +} + +impl From<&[String]> for StringVec { + fn from(slice: &[String]) -> Self { + StringVec { + vec: slice.to_vec(), + } + } +} + +impl From<Vec<&str>> for StringVec { + fn from(vec: Vec<&str>) -> Self { + StringVec { + vec: vec.iter().map(|&s| s.to_string()).collect(), + } + } +} |
