summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-03-17 14:56:44 +0800
committer魏曹先生 <1992414357@qq.com>2026-03-17 14:56:44 +0800
commit2e11849a23de0533b172fe2bb057fc3553a36cc1 (patch)
treededbb6e269198f3d9039e5a5024964e5d995b7a8
parent775b3613f3ece75f7673ea1be6b6ec420c2bb76b (diff)
Handle early command output in prepare phase
-rw-r--r--src/bin/jvn.rs6
-rw-r--r--src/systems/cmd/cmd_system.rs16
-rw-r--r--src/systems/cmd/errors.rs5
-rw-r--r--src/systems/cmd/macros.rs21
4 files changed, 44 insertions, 4 deletions
diff --git a/src/bin/jvn.rs b/src/bin/jvn.rs
index b051c51..062eab8 100644
--- a/src/bin/jvn.rs
+++ b/src/bin/jvn.rs
@@ -279,6 +279,12 @@ fn handle_prepare_error(cmd_prepare_error: CmdPrepareError) {
CmdPrepareError::NoSheetInUse => {
eprintln!("{}", md(t!("prepare_error.no_sheet_in_use")));
}
+ CmdPrepareError::EarlyOutput(_) => {
+ // Early output is not an error
+ // No additional handling needed,
+ // this result has already been captured in `crate::systems::cmd::cmd_system.rs`
+ exit(0)
+ }
}
}
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<dyn std::any::Any + Send + 'static>,
+ std::any::TypeId::of::<$t>(),
+ )))
+ }};
+}