diff options
Diffstat (limited to 'src/systems/cmd/cmd_system.rs')
| -rw-r--r-- | src/systems/cmd/cmd_system.rs | 50 |
1 files changed, 35 insertions, 15 deletions
diff --git a/src/systems/cmd/cmd_system.rs b/src/systems/cmd/cmd_system.rs index 65f972d..20f5aef 100644 --- a/src/systems/cmd/cmd_system.rs +++ b/src/systems/cmd/cmd_system.rs @@ -14,11 +14,12 @@ pub struct JVCommandContext { pub confirmed: bool, } -pub trait JVCommand<Argument, Input, Output, Renderer> +pub trait JVCommand<Argument, Input, Collect, Output, Renderer> where - Argument: clap::Parser + Send + Sync, - Input: Send + Sync, + Argument: clap::Parser + Send, + Input: Send, Output: Serialize + Send + Sync, + Collect: Send, Renderer: JVResultRenderer<Output> + Send + Sync, { /// Get help string for the command @@ -52,7 +53,7 @@ where /// Process the command output with a custom renderer, /// performing any necessary post-execution processing - fn process_with_renderer<R: JVResultRenderer<Output> + Send + Sync>( + fn process_with_renderer<R: JVResultRenderer<Output> + Send>( args: Vec<String>, ctx: JVCommandContext, ) -> impl Future<Output = Result<JVRenderResult, CmdProcessError>> + Send @@ -61,40 +62,59 @@ where { async move { let mut full_args = vec!["jv".to_string()]; + full_args.extend(args); + let parsed_args = match Argument::try_parse_from(full_args) { Ok(args) => args, Err(_) => return Err(CmdProcessError::ParseError(Self::get_help_str())), }; + // If the help flag is used, skip execution and directly print help if ctx.help { let mut r = JVRenderResult::default(); r_println!(r, "{}", Self::get_help_str()); return Ok(r); } - let input = match Self::prepare(parsed_args, ctx).await { - Ok(input) => input, + + let (input, collect) = match tokio::try_join!( + Self::prepare(&parsed_args, &ctx), + Self::collect(&parsed_args, &ctx) + ) { + Ok((input, collect)) => (input, collect), Err(e) => return Err(CmdProcessError::from(e)), }; - let output = match Self::exec(input).await { + + let output = match Self::exec(input, collect).await { Ok(output) => output, Err(e) => return Err(CmdProcessError::from(e)), }; + match R::render(&output).await { Ok(r) => Ok(r), Err(e) => Err(CmdProcessError::from(e)), } } } - - /// Prepare to run the command, - /// converting Clap input into the command's supported input + /// Prepare + /// Converts Argument input into parameters readable during the execution phase fn prepare( - args: Argument, - ctx: JVCommandContext, + args: &Argument, + ctx: &JVCommandContext, ) -> impl Future<Output = Result<Input, CmdPrepareError>> + Send; - /// Run the command phase, - /// returning an output structure, waiting for rendering - fn exec(input: Input) -> impl Future<Output = Result<Output, CmdExecuteError>> + Send; + /// Resource collection + /// Reads required resources and sends them to the `exec` function + fn collect( + args: &Argument, + ctx: &JVCommandContext, + ) -> impl Future<Output = Result<Collect, CmdPrepareError>> + Send; + + /// Execute + /// Executes the results obtained from `prepare` and `collect` + /// Returns data that can be used for rendering + fn exec( + input: Input, + collect: Collect, + ) -> impl Future<Output = Result<Output, CmdExecuteError>> + Send; } |
