diff options
Diffstat (limited to 'mingling_core/src')
| -rw-r--r-- | mingling_core/src/asset/dispatcher.rs | 12 | ||||
| -rw-r--r-- | mingling_core/src/program.rs | 56 | ||||
| -rw-r--r-- | mingling_core/src/program/exec.rs | 41 | ||||
| -rw-r--r-- | mingling_core/src/program/flag.rs | 9 | ||||
| -rw-r--r-- | mingling_core/src/program/setup.rs | 8 | ||||
| -rw-r--r-- | mingling_core/src/program/setup/basic.rs | 7 | ||||
| -rw-r--r-- | mingling_core/src/program/setup/general_renderer.rs | 12 |
7 files changed, 59 insertions, 86 deletions
diff --git a/mingling_core/src/asset/dispatcher.rs b/mingling_core/src/asset/dispatcher.rs index 72b31e9..761c399 100644 --- a/mingling_core/src/asset/dispatcher.rs +++ b/mingling_core/src/asset/dispatcher.rs @@ -6,16 +6,16 @@ use crate::{ChainProcess, Program, asset::node::Node}; /// /// Note: If you are using [mingling_macros](https://crates.io/crates/mingling_macros), /// you can use the `dispatcher!("node.subnode", CommandType => Entry)` macro to declare a `Dispatcher` -pub trait Dispatcher<G> { +pub trait Dispatcher<C> { /// Returns a command node for matching user input fn node(&self) -> Node; /// Returns a [ChainProcess](./enum.ChainProcess.html) based on user input arguments, /// to be sent to the specific invocation - fn begin(&self, args: Vec<String>) -> ChainProcess<G>; + fn begin(&self, args: Vec<String>) -> ChainProcess<C>; /// Clones the current dispatcher for implementing the `Clone` trait - fn clone_dispatcher(&self) -> Box<dyn Dispatcher<G>>; + fn clone_dispatcher(&self) -> Box<dyn Dispatcher<C>>; } impl<G> Clone for Box<dyn Dispatcher<G>> @@ -27,11 +27,11 @@ where } } -impl<C: crate::program::ProgramCollect, G: Display> Program<C, G> { +impl<C: crate::program::ProgramCollect> Program<C> { /// Adds a dispatcher to the program. pub fn with_dispatcher<Disp>(&mut self, dispatcher: Disp) where - Disp: Dispatcher<G> + Send + Sync + 'static, + Disp: Dispatcher<C> + Send + Sync + 'static, { self.dispatcher.push(Box::new(dispatcher)); } @@ -39,7 +39,7 @@ impl<C: crate::program::ProgramCollect, G: Display> Program<C, G> { /// Add some dispatchers to the program. pub fn with_dispatchers<D>(&mut self, dispatchers: D) where - D: Into<Dispatchers<G>>, + D: Into<Dispatchers<C>>, { let dispatchers = dispatchers.into(); self.dispatcher.extend(dispatchers.dispatcher); diff --git a/mingling_core/src/program.rs b/mingling_core/src/program.rs index a671e9b..c9cffbe 100644 --- a/mingling_core/src/program.rs +++ b/mingling_core/src/program.rs @@ -35,7 +35,7 @@ pub use string_vec::*; static THIS_PROGRAM: OnceLock<Option<Box<dyn std::any::Any + Send + Sync>>> = OnceLock::new(); /// Returns a reference to the current program instance, panics if not set. -pub fn this<C>() -> &'static Program<C, C> +pub fn this<C>() -> &'static Program<C> where C: ProgramCollect + 'static, { @@ -43,27 +43,23 @@ where } /// Returns a reference to the current program instance, if set. -fn try_get_this_program<C>() -> Option<&'static Program<C, C>> +fn try_get_this_program<C>() -> Option<&'static Program<C>> where C: ProgramCollect + 'static, { - THIS_PROGRAM - .get()? - .as_ref()? - .downcast_ref::<Program<C, C>>() + THIS_PROGRAM.get()?.as_ref()?.downcast_ref::<Program<C>>() } /// Program, used to define the behavior of the entire command-line program #[derive(Default)] -pub struct Program<C, G> +pub struct Program<C> where C: ProgramCollect, { pub(crate) collect: std::marker::PhantomData<C>, - pub(crate) group: std::marker::PhantomData<G>, pub(crate) args: Vec<String>, - pub(crate) dispatcher: Vec<Box<dyn Dispatcher<G> + Send + Sync>>, + pub(crate) dispatcher: Vec<Box<dyn Dispatcher<C> + Send + Sync>>, pub stdout_setting: ProgramStdoutSetting, pub user_context: ProgramUserContext, @@ -72,9 +68,9 @@ where pub general_renderer_name: GeneralRendererSetting, } -impl<C, G> Program<C, G> +impl<C> Program<C> where - C: ProgramCollect<Enum = G>, + C: ProgramCollect<Enum = C>, { /// Creates a new Program instance, initializing command-line arguments from the environment. pub fn new() -> Self { @@ -98,7 +94,6 @@ where pub fn new_with_args(args: impl Into<StringVec>) -> Self { Program { collect: std::marker::PhantomData, - group: std::marker::PhantomData, args: args.into().into(), dispatcher: Vec::new(), stdout_setting: Default::default(), @@ -110,22 +105,21 @@ where } /// Returns a reference to the current program instance, if set. - pub fn this_program() -> &'static Program<C, G> + pub fn this_program() -> &'static Program<C> where C: 'static, - G: 'static, { THIS_PROGRAM .get() .unwrap() .as_ref() .unwrap() - .downcast_ref::<Program<C, G>>() + .downcast_ref::<Program<C>>() .unwrap() } /// Get all registered dispatcher names from the program - pub fn get_nodes(&self) -> Vec<(String, &(dyn Dispatcher<G> + Send + Sync))> { + pub fn get_nodes(&self) -> Vec<(String, &(dyn Dispatcher<C> + Send + Sync))> { get_nodes(self) } @@ -133,7 +127,7 @@ where pub fn dispatch_args_dynamic( &self, args: impl Into<StringVec>, - ) -> Result<AnyOutput<G>, ChainProcessError> { + ) -> Result<AnyOutput<C>, ChainProcessError> { match exec::dispatch_args_dynamic(self, args.into().into()) { Ok(ok) => Ok(ok), Err(e) => Err(e.into()), @@ -143,16 +137,15 @@ where // Async program #[cfg(feature = "async")] -impl<C, G> Program<C, G> +impl<C> Program<C> where - C: ProgramCollect<Enum = G>, + C: ProgramCollect<Enum = C>, { /// Sets the current program instance and runs the provided async function. async fn set_instance_and_run<F, Fut>(self, f: F) -> Fut::Output where C: 'static + Send + Sync, - G: 'static + Send + Sync, - F: FnOnce(&'static Program<C, G>) -> Fut + Send + Sync, + F: FnOnce(&'static Program<C>) -> Fut + Send + Sync, Fut: Future + Send, { THIS_PROGRAM.get_or_init(|| Some(Box::new(self))); @@ -161,7 +154,7 @@ where .unwrap() .as_ref() .unwrap() - .downcast_ref::<Program<C, G>>() + .downcast_ref::<Program<C>>() .unwrap(); f(program).await } @@ -170,7 +163,6 @@ where pub async fn exec_without_render(mut self) -> Result<RenderResult, ProgramExecuteError> where C: 'static + Send + Sync, - G: 'static + Send + Sync, { self.args = self.args.iter().skip(1).cloned().collect(); self.set_instance_and_run(|p| async { crate::exec::exec(p).await.map_err(|e| e.into()) }) @@ -181,7 +173,6 @@ where pub async fn exec(self) where C: 'static + Send + Sync, - G: 'static + Send + Sync, { let stdout_setting = self.stdout_setting.clone(); let result = match self.exec_without_render().await { @@ -216,16 +207,15 @@ where // Sync program #[cfg(not(feature = "async"))] -impl<C, G> Program<C, G> +impl<C> Program<C> where - C: ProgramCollect<Enum = G>, + C: ProgramCollect<Enum = C>, { /// Sets the current program instance and runs the provided function. fn set_instance_and_run<F, R>(self, f: F) -> R where C: 'static + Send + Sync, - G: 'static + Send + Sync, - F: FnOnce(&'static Program<C, G>) -> R + Send + Sync, + F: FnOnce(&'static Program<C>) -> R + Send + Sync, { THIS_PROGRAM.get_or_init(|| Some(Box::new(self))); let program = THIS_PROGRAM @@ -233,7 +223,7 @@ where .unwrap() .as_ref() .unwrap() - .downcast_ref::<Program<C, G>>() + .downcast_ref::<Program<C>>() .unwrap(); f(program) } @@ -242,7 +232,6 @@ where pub fn exec_without_render(mut self) -> Result<RenderResult, ProgramExecuteError> where C: 'static + Send + Sync, - G: 'static + Send + Sync, { self.args = self.args.iter().skip(1).cloned().collect(); self.set_instance_and_run(|p| crate::exec::exec(p).map_err(|e| e.into())) @@ -252,7 +241,6 @@ where pub fn exec(self) where C: 'static + Send + Sync, - G: 'static + Send + Sync, { let stdout_setting = self.stdout_setting.clone(); let result = match self.exec_without_render() { @@ -403,9 +391,9 @@ macro_rules! __dispatch_program_chains { } /// Get all registered dispatcher names from the program -pub fn get_nodes<C: ProgramCollect<Enum = G>, G>( - program: &Program<C, G>, -) -> Vec<(String, &(dyn Dispatcher<G> + Send + Sync))> { +pub fn get_nodes<C: ProgramCollect<Enum = C>>( + program: &Program<C>, +) -> Vec<(String, &(dyn Dispatcher<C> + Send + Sync))> { program .dispatcher .iter() diff --git a/mingling_core/src/program/exec.rs b/mingling_core/src/program/exec.rs index 68a694e..c1eada5 100644 --- a/mingling_core/src/program/exec.rs +++ b/mingling_core/src/program/exec.rs @@ -9,11 +9,9 @@ use crate::{ pub mod error; #[cfg(feature = "async")] -pub async fn exec<C, G>( - program: &Program<C, G>, -) -> Result<RenderResult, ProgramInternalExecuteError> +pub async fn exec<C>(program: &Program<C>) -> Result<RenderResult, ProgramInternalExecuteError> where - C: ProgramCollect<Enum = G>, + C: ProgramCollect<Enum = C>, { let mut current = dispatch_args_dynamic(program, program.args.clone())?; let mut stop_next = false; @@ -26,7 +24,7 @@ where if C::has_chain(¤t) { match C::do_chain(current).await { ChainProcess::Ok((any, Next::Renderer)) => { - return Ok(render::<C, G>(program, any)); + return Ok(render::<C>(program, any)); } ChainProcess::Ok((any, Next::Chain)) => any, ChainProcess::Err(e) => return Err(e.into()), @@ -34,7 +32,7 @@ where } // If no chain exists, attempt to render else if C::has_renderer(¤t) { - return Ok(render::<C, G>(program, current)); + return Ok(render::<C>(program, current)); } // No renderer exists else { @@ -51,9 +49,9 @@ where } #[cfg(not(feature = "async"))] -pub fn exec<C, G>(program: &Program<C, G>) -> Result<RenderResult, ProgramInternalExecuteError> +pub fn exec<C>(program: &Program<C>) -> Result<RenderResult, ProgramInternalExecuteError> where - C: ProgramCollect<Enum = G>, + C: ProgramCollect<Enum = C>, { let mut current = dispatch_args_dynamic(program, program.args.clone())?; let mut stop_next = false; @@ -66,7 +64,7 @@ where if C::has_chain(¤t) { match C::do_chain(current) { ChainProcess::Ok((any, Next::Renderer)) => { - return Ok(render::<C, G>(program, any)); + return Ok(render::<C>(program, any)); } ChainProcess::Ok((any, Next::Chain)) => any, ChainProcess::Err(e) => return Err(e.into()), @@ -74,7 +72,7 @@ where } // If no chain exists, attempt to render else if C::has_renderer(¤t) { - return Ok(render::<C, G>(program, current)); + return Ok(render::<C>(program, current)); } // No renderer exists else { @@ -91,12 +89,12 @@ where } /// Dynamically dispatch input arguments to registered entry types -pub(crate) fn dispatch_args_dynamic<C, G>( - program: &Program<C, G>, +pub(crate) fn dispatch_args_dynamic<C>( + program: &Program<C>, args: Vec<String>, -) -> Result<AnyOutput<G>, ProgramInternalExecuteError> +) -> Result<AnyOutput<C>, ProgramInternalExecuteError> where - C: ProgramCollect<Enum = G>, + C: ProgramCollect<Enum = C>, { let next = match match_user_input(program, args) { Ok((dispatcher, args)) => { @@ -117,18 +115,18 @@ 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, G>( - program: &Program<C, G>, +pub(crate) fn match_user_input<C>( + program: &Program<C>, args: Vec<String>, -) -> Result<(&(dyn Dispatcher<G> + Send + Sync), Vec<String>), ProgramInternalExecuteError> +) -> Result<(&(dyn Dispatcher<C> + Send + Sync), Vec<String>), ProgramInternalExecuteError> where - C: ProgramCollect<Enum = G>, + C: ProgramCollect<Enum = C>, { let nodes = program.get_nodes(); let command = format!("{} ", args.join(" ")); // Find all nodes that match the command prefix - let matching_nodes: Vec<&(String, &(dyn Dispatcher<G> + Send + Sync))> = nodes + let matching_nodes: Vec<&(String, &(dyn Dispatcher<C> + Send + Sync))> = nodes .iter() // Also add a space to the node string to ensure consistent matching logic .filter(|(node_str, _)| command.starts_with(&format!("{} ", node_str))) @@ -162,10 +160,7 @@ where #[inline(always)] #[allow(unused_variables)] -fn render<C: ProgramCollect<Enum = G>, G>( - program: &Program<C, G>, - any: AnyOutput<G>, -) -> RenderResult { +fn render<C: ProgramCollect<Enum = C>>(program: &Program<C>, any: AnyOutput<C>) -> RenderResult { #[cfg(not(feature = "general_renderer"))] { let mut render_result = RenderResult::default(); diff --git a/mingling_core/src/program/flag.rs b/mingling_core/src/program/flag.rs index f44cf33..0ab8d1c 100644 --- a/mingling_core/src/program/flag.rs +++ b/mingling_core/src/program/flag.rs @@ -1,5 +1,3 @@ -use std::fmt::Display; - use crate::{Program, ProgramCollect}; /// A wrapper for a collection of static string slices representing command-line flags or arguments. @@ -474,15 +472,14 @@ mod tests { } } -impl<C, G> Program<C, G> +impl<C> Program<C> where C: ProgramCollect, - G: Display, { /// Registers a global argument (with value) and its handler. pub fn global_argument<F, A>(&mut self, arguments: A, mut do_fn: F) where - F: FnMut(&mut Program<C, G>, String), + F: FnMut(&mut Program<C>, String), A: Into<Flag>, { let flag = arguments.into(); @@ -498,7 +495,7 @@ where /// Registers a global flag (boolean) and its handler. pub fn global_flag<F, A>(&mut self, flag: A, mut do_fn: F) where - F: FnMut(&mut Program<C, G>), + F: FnMut(&mut Program<C>), A: Into<Flag>, { let flag = flag.into(); diff --git a/mingling_core/src/program/setup.rs b/mingling_core/src/program/setup.rs index f095ed3..86228b9 100644 --- a/mingling_core/src/program/setup.rs +++ b/mingling_core/src/program/setup.rs @@ -8,19 +8,19 @@ mod general_renderer; #[cfg(feature = "general_renderer")] pub use general_renderer::*; -pub trait ProgramSetup<C, G> +pub trait ProgramSetup<C> where C: ProgramCollect, { - fn setup(&mut self, program: &mut Program<C, G>); + fn setup(&mut self, program: &mut Program<C>); } -impl<C, G> Program<C, G> +impl<C> Program<C> where C: ProgramCollect, { /// Load and execute init logic - pub fn with_setup<S: ProgramSetup<C, G> + 'static>(&mut self, mut setup: S) -> S { + pub fn with_setup<S: ProgramSetup<C> + 'static>(&mut self, mut setup: S) -> S { S::setup(&mut setup, self); setup } diff --git a/mingling_core/src/program/setup/basic.rs b/mingling_core/src/program/setup/basic.rs index 8316a33..43c14b9 100644 --- a/mingling_core/src/program/setup/basic.rs +++ b/mingling_core/src/program/setup/basic.rs @@ -1,5 +1,3 @@ -use std::fmt::Display; - use crate::{ ProgramCollect, program::{Program, setup::ProgramSetup}, @@ -12,12 +10,11 @@ use crate::{ /// - Collects `--confirm` flag to skip user confirmation pub struct BasicProgramSetup; -impl<C, G> ProgramSetup<C, G> for BasicProgramSetup +impl<C> ProgramSetup<C> for BasicProgramSetup where C: ProgramCollect, - G: Display, { - fn setup(&mut self, program: &mut Program<C, G>) { + fn setup(&mut self, program: &mut Program<C>) { program.global_flag(["--quiet", "-q"], |p| { p.stdout_setting.render_output = false; p.stdout_setting.error_output = false; diff --git a/mingling_core/src/program/setup/general_renderer.rs b/mingling_core/src/program/setup/general_renderer.rs index 035f813..2d2ee79 100644 --- a/mingling_core/src/program/setup/general_renderer.rs +++ b/mingling_core/src/program/setup/general_renderer.rs @@ -1,5 +1,3 @@ -use std::fmt::Display; - use crate::{ ProgramCollect, program::{Program, setup::ProgramSetup}, @@ -10,12 +8,11 @@ use crate::{ /// - Adds a `--renderer` global argument to specify the renderer type pub struct GeneralRendererSimpleSetup; -impl<C, G> ProgramSetup<C, G> for GeneralRendererSimpleSetup +impl<C> ProgramSetup<C> for GeneralRendererSimpleSetup where C: ProgramCollect, - G: Display, { - fn setup(&mut self, program: &mut Program<C, G>) { + fn setup(&mut self, program: &mut Program<C>) { program.global_argument("--renderer", |p, renderer| { p.general_renderer_name = renderer.into(); }); @@ -33,12 +30,11 @@ where /// * `--ron-pretty` for pretty-printed RON output pub struct GeneralRendererSetup; -impl<C, G> ProgramSetup<C, G> for GeneralRendererSetup +impl<C> ProgramSetup<C> for GeneralRendererSetup where C: ProgramCollect, - G: Display, { - fn setup(&mut self, program: &mut Program<C, G>) { + fn setup(&mut self, program: &mut Program<C>) { program.global_flag("--json", |p| { p.general_renderer_name = crate::GeneralRendererSetting::Json }); |
