From 49b9037168fb5b6c8deb7ab06abbfd6f54ebc798 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Sat, 24 Jan 2026 03:10:41 +0800 Subject: Split prepare phase into prepare and collect - Prepare now handles argument-to-input conversion only - Collect handles resource gathering and data collection - Status command updated to use new two-phase structure - Command system trait modified to support separate phases --- src/systems/cmd/cmd_system.rs | 50 ++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 15 deletions(-) (limited to 'src/systems') 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 +pub trait JVCommand where - Argument: clap::Parser + Send + Sync, - Input: Send + Sync, + Argument: clap::Parser + Send, + Input: Send, Output: Serialize + Send + Sync, + Collect: Send, Renderer: JVResultRenderer + 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 + Send + Sync>( + fn process_with_renderer + Send>( args: Vec, ctx: JVCommandContext, ) -> impl Future> + 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> + Send; - /// Run the command phase, - /// returning an output structure, waiting for rendering - fn exec(input: Input) -> impl Future> + Send; + /// Resource collection + /// Reads required resources and sends them to the `exec` function + fn collect( + args: &Argument, + ctx: &JVCommandContext, + ) -> impl Future> + 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> + Send; } -- cgit