summaryrefslogtreecommitdiff
path: root/src/systems/cmd/cmd_system.rs
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-01-24 03:10:41 +0800
committer魏曹先生 <1992414357@qq.com>2026-01-24 03:10:41 +0800
commit49b9037168fb5b6c8deb7ab06abbfd6f54ebc798 (patch)
tree0f5b7c6ce67f2561b2e00da4331df09f476345d4 /src/systems/cmd/cmd_system.rs
parentf9fa7d65d775959efbc9609ccafd1fdce76129e4 (diff)
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
Diffstat (limited to 'src/systems/cmd/cmd_system.rs')
-rw-r--r--src/systems/cmd/cmd_system.rs50
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;
}