From 2e11849a23de0533b172fe2bb057fc3553a36cc1 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Tue, 17 Mar 2026 14:56:44 +0800 Subject: Handle early command output in prepare phase --- src/systems/cmd/cmd_system.rs | 16 ++++++++++++---- src/systems/cmd/errors.rs | 5 +++++ src/systems/cmd/macros.rs | 21 +++++++++++++++++++++ 3 files changed, 38 insertions(+), 4 deletions(-) (limited to 'src/systems') diff --git a/src/systems/cmd/cmd_system.rs b/src/systems/cmd/cmd_system.rs index 7272c9e..43d5187 100644 --- a/src/systems/cmd/cmd_system.rs +++ b/src/systems/cmd/cmd_system.rs @@ -134,10 +134,18 @@ where Self::collect(&parsed_args, &ctx) ) { Ok((input, collect)) => (input, collect), - Err(e) => { - error!("{}", t!("verbose.cmd_process_prepare_failed")); - return Err(CmdProcessError::from(e)); - } + Err(e) => match e { + CmdPrepareError::EarlyOutput(any_output) => { + // Early output is not an "error" + // It's just that when the result can be determined early, + // there's no need to wait until the execution phase to inform the user + return Ok(any_output); + } + _ => { + error!("{}", t!("verbose.cmd_process_prepare_failed")); + return Err(CmdProcessError::from(e)); + } + }, }; info!("{}", t!("verbose.cmd_process_exec")); diff --git a/src/systems/cmd/errors.rs b/src/systems/cmd/errors.rs index abde5de..efa12a9 100644 --- a/src/systems/cmd/errors.rs +++ b/src/systems/cmd/errors.rs @@ -1,5 +1,7 @@ use just_enough_vcs::lib::data::{member::MemberId, sheet::SheetName}; +use crate::systems::cmd::cmd_system::AnyOutput; + #[derive(thiserror::Error, Debug)] pub enum CmdPrepareError { #[error("IO error: {0}")] @@ -32,6 +34,9 @@ pub enum CmdPrepareError { #[error("No sheet in use")] NoSheetInUse, + + #[error("Error occurred and returned early")] + EarlyOutput(AnyOutput), } impl CmdPrepareError { diff --git a/src/systems/cmd/macros.rs b/src/systems/cmd/macros.rs index 5763961..37b041c 100644 --- a/src/systems/cmd/macros.rs +++ b/src/systems/cmd/macros.rs @@ -163,6 +163,11 @@ macro_rules! command_template { } #[macro_export] +/// `cmd_output!` 宏应在命令的 `exec` 函数中使用。 +/// 它负责将执行结果包装成能被指定渲染器匹配的格式。 +/// +/// 注意:该宏不仅是简化输出的工具,更是 JvcsCLI 代码生成流程的必要组成部分。 +/// 因此,所有命令的输出都必须通过此宏返回。 macro_rules! cmd_output { ($t:ty => $v:expr) => {{ let checked_value: $t = $v; @@ -172,3 +177,19 @@ macro_rules! cmd_output { )) }}; } + +#[macro_export] +/// `early_cmd_output!` 宏应在命令的 `prepare` 或 `collect` 函数中使用。 +/// 它负责将执行结果包装成能返回到核心 +/// +/// 注意:该宏不仅是简化输出的工具,更是 JvcsCLI 代码生成流程的必要组成部分。 +/// 因此,所有命令的输出都必须通过此宏返回。 +macro_rules! early_cmd_output { + ($t:ty => $v:expr) => {{ + let checked_value: $t = $v; + Err(crate::systems::cmd::errors::CmdPrepareError::EarlyOutput(( + Box::new(checked_value) as Box, + std::any::TypeId::of::<$t>(), + ))) + }}; +} -- cgit