summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-03-15 22:57:36 +0800
committer魏曹先生 <1992414357@qq.com>2026-03-15 22:57:36 +0800
commit0a6b6c1d213e19c7649e343c2a77f3399feb8016 (patch)
tree9c2e0fbf51a1f6e80f5a623ad094be2b62782607 /src
parent71145f72947033bbc5125e14ea89f8d68c189da4 (diff)
Add build system rerun triggers and refactor command system
Diffstat (limited to 'src')
-rw-r--r--src/cmds/cmd/helpdoc.rs8
-rw-r--r--src/cmds/cmd/helpdoc_list.rs8
-rw-r--r--src/cmds/cmd/hexdump.rs9
-rw-r--r--src/cmds/cmd/sheetdump.rs9
-rw-r--r--src/cmds/cmd/sheetedit.rs9
-rw-r--r--src/cmds/cmd/version.rs8
-rw-r--r--src/cmds/cmd/workspace_create.rs8
-rw-r--r--src/cmds/cmd/workspace_init.rs8
-rw-r--r--src/cmds/converter/workspace_operation_error.rs3
-rw-r--r--src/systems/cmd/cmd_system.rs9
-rw-r--r--src/systems/cmd/macros.rs88
11 files changed, 72 insertions, 95 deletions
diff --git a/src/cmds/cmd/helpdoc.rs b/src/cmds/cmd/helpdoc.rs
index 98e0309..74f4c7e 100644
--- a/src/cmds/cmd/helpdoc.rs
+++ b/src/cmds/cmd/helpdoc.rs
@@ -6,14 +6,13 @@ use crate::{
},
systems::{
cmd::{
- cmd_system::JVCommandContext,
+ cmd_system::{AnyOutput, JVCommandContext},
errors::{CmdExecuteError, CmdPrepareError},
},
helpdoc::{DEFAULT_HELPDOC, helpdoc_viewer},
},
};
use cmd_system_macros::exec;
-use std::any::TypeId;
pub struct JVHelpdocCommand;
type Cmd = JVHelpdocCommand;
@@ -38,10 +37,7 @@ async fn collect(_args: &Arg, _ctx: &JVCommandContext) -> Result<Collect, CmdPre
}
#[exec]
-async fn exec(
- input: In,
- _collect: Collect,
-) -> Result<(Box<dyn std::any::Any + Send + 'static>, TypeId), CmdExecuteError> {
+async fn exec(input: In, _collect: Collect) -> Result<AnyOutput, CmdExecuteError> {
helpdoc_viewer::display_with_lang(&input.name.as_str(), &input.lang.as_str()).await;
cmd_output!(JVNoneOutput => JVNoneOutput)
}
diff --git a/src/cmds/cmd/helpdoc_list.rs b/src/cmds/cmd/helpdoc_list.rs
index b4b05cf..6b81b16 100644
--- a/src/cmds/cmd/helpdoc_list.rs
+++ b/src/cmds/cmd/helpdoc_list.rs
@@ -6,14 +6,13 @@ use crate::{
},
systems::{
cmd::{
- cmd_system::JVCommandContext,
+ cmd_system::{AnyOutput, JVCommandContext},
errors::{CmdExecuteError, CmdPrepareError},
},
helpdoc::{DEFAULT_HELPDOC, get_helpdoc_list, helpdoc_viewer},
},
};
use cmd_system_macros::exec;
-use std::any::TypeId;
pub struct JVHelpdocListCommand;
type Cmd = JVHelpdocListCommand;
@@ -35,10 +34,7 @@ async fn collect(_args: &Arg, _ctx: &JVCommandContext) -> Result<Collect, CmdPre
}
#[exec]
-async fn exec(
- _input: In,
- _collect: Collect,
-) -> Result<(Box<dyn std::any::Any + Send + 'static>, TypeId), CmdExecuteError> {
+async fn exec(_input: In, _collect: Collect) -> Result<AnyOutput, CmdExecuteError> {
let output = JVHelpdocsOutput {
names: get_helpdoc_list().into_iter().map(String::from).collect(),
};
diff --git a/src/cmds/cmd/hexdump.rs b/src/cmds/cmd/hexdump.rs
index 928b626..346fffe 100644
--- a/src/cmds/cmd/hexdump.rs
+++ b/src/cmds/cmd/hexdump.rs
@@ -1,5 +1,3 @@
-use std::any::TypeId;
-
use crate::{
cmd_output,
cmds::{
@@ -8,7 +6,7 @@ use crate::{
},
systems::{
cmd::{
- cmd_system::JVCommandContext,
+ cmd_system::{AnyOutput, JVCommandContext},
errors::{CmdExecuteError, CmdPrepareError},
},
helpdoc::helpdoc_viewer,
@@ -39,10 +37,7 @@ async fn collect(args: &Arg, _ctx: &JVCommandContext) -> Result<Collect, CmdPrep
}
#[exec]
-async fn exec(
- _input: In,
- collect: Collect,
-) -> Result<(Box<dyn std::any::Any + Send + 'static>, TypeId), CmdExecuteError> {
+async fn exec(_input: In, collect: Collect) -> Result<AnyOutput, CmdExecuteError> {
let output = JVHexOutput { data: collect.data };
cmd_output!(JVHexOutput => output)
}
diff --git a/src/cmds/cmd/sheetdump.rs b/src/cmds/cmd/sheetdump.rs
index 8140a0d..5877253 100644
--- a/src/cmds/cmd/sheetdump.rs
+++ b/src/cmds/cmd/sheetdump.rs
@@ -1,5 +1,3 @@
-use std::any::TypeId;
-
use crate::{
cmd_output,
cmds::{
@@ -10,7 +8,7 @@ use crate::{
},
systems::{
cmd::{
- cmd_system::JVCommandContext,
+ cmd_system::{AnyOutput, JVCommandContext},
errors::{CmdExecuteError, CmdPrepareError},
},
helpdoc::helpdoc_viewer,
@@ -54,10 +52,7 @@ async fn collect(args: &Arg, _ctx: &JVCommandContext) -> Result<Collect, CmdPrep
}
#[exec]
-async fn exec(
- input: In,
- collect: Collect,
-) -> Result<(Box<dyn std::any::Any + Send + 'static>, TypeId), CmdExecuteError> {
+async fn exec(input: In, collect: Collect) -> Result<AnyOutput, CmdExecuteError> {
let mappings = collect.sheet.mappings();
let mut mappings_vec = mappings.iter().cloned().collect::<Vec<LocalMapping>>();
if input.sort {
diff --git a/src/cmds/cmd/sheetedit.rs b/src/cmds/cmd/sheetedit.rs
index 08918f4..a751a64 100644
--- a/src/cmds/cmd/sheetedit.rs
+++ b/src/cmds/cmd/sheetedit.rs
@@ -6,7 +6,7 @@ use crate::{
},
systems::{
cmd::{
- cmd_system::JVCommandContext,
+ cmd_system::{AnyOutput, JVCommandContext},
errors::{CmdExecuteError, CmdPrepareError},
},
helpdoc::helpdoc_viewer,
@@ -20,7 +20,7 @@ use cmd_system_macros::exec;
use just_enough_vcs::system::sheet_system::{mapping::LocalMapping, sheet::SheetData};
use just_fmt::fmt_path::{PathFormatError, fmt_path};
use rust_i18n::t;
-use std::{any::TypeId, borrow::Cow, path::PathBuf};
+use std::{borrow::Cow, path::PathBuf};
use tokio::fs::create_dir_all;
pub struct JVSheeteditCommand;
@@ -52,10 +52,7 @@ async fn collect(args: &Arg, _ctx: &JVCommandContext) -> Result<Collect, CmdPrep
}
#[exec]
-async fn exec(
- input: In,
- collect: Collect,
-) -> Result<(Box<dyn std::any::Any + Send + 'static>, TypeId), CmdExecuteError> {
+async fn exec(input: In, collect: Collect) -> Result<AnyOutput, CmdExecuteError> {
let sheet = SheetData::try_from(collect.data).unwrap_or(SheetData::empty());
let mappings = sheet.mappings();
diff --git a/src/cmds/cmd/version.rs b/src/cmds/cmd/version.rs
index 7a2e45b..2e5d8b6 100644
--- a/src/cmds/cmd/version.rs
+++ b/src/cmds/cmd/version.rs
@@ -8,7 +8,7 @@ use crate::{
data::compile_info::CompileInfo,
systems::{
cmd::{
- cmd_system::JVCommandContext,
+ cmd_system::{AnyOutput, JVCommandContext},
errors::{CmdExecuteError, CmdPrepareError},
},
helpdoc::helpdoc_viewer,
@@ -16,7 +16,6 @@ use crate::{
};
use cmd_system_macros::exec;
use just_enough_vcs::data::compile_info::CoreCompileInfo;
-use std::any::TypeId;
pub struct JVVersionCommand;
type Cmd = JVVersionCommand;
@@ -44,10 +43,7 @@ async fn collect(_args: &Arg, _ctx: &JVCommandContext) -> Result<Collect, CmdPre
}
#[exec]
-async fn exec(
- input: In,
- collect: Collect,
-) -> Result<(Box<dyn std::any::Any + Send + 'static>, TypeId), CmdExecuteError> {
+async fn exec(input: In, collect: Collect) -> Result<AnyOutput, CmdExecuteError> {
let output = JVVersionInputOutputConverter::merge_to_output(input, collect);
cmd_output!(JVVersionOutput => output)
}
diff --git a/src/cmds/cmd/workspace_create.rs b/src/cmds/cmd/workspace_create.rs
index c5f8c8e..1c983f6 100644
--- a/src/cmds/cmd/workspace_create.rs
+++ b/src/cmds/cmd/workspace_create.rs
@@ -7,7 +7,7 @@ use crate::{
},
systems::{
cmd::{
- cmd_system::JVCommandContext,
+ cmd_system::{AnyOutput, JVCommandContext},
errors::{CmdExecuteError, CmdPrepareError},
},
helpdoc::helpdoc_viewer,
@@ -15,7 +15,6 @@ use crate::{
};
use cmd_system_macros::exec;
use just_enough_vcs::system::workspace::func::create_workspace;
-use std::any::TypeId;
pub struct JVWorkspaceCreateCommand;
type Cmd = JVWorkspaceCreateCommand;
@@ -39,10 +38,7 @@ async fn collect(_args: &Arg, _ctx: &JVCommandContext) -> Result<Collect, CmdPre
}
#[exec]
-async fn exec(
- input: In,
- _collect: Collect,
-) -> Result<(Box<dyn std::any::Any + Send + 'static>, TypeId), CmdExecuteError> {
+async fn exec(input: In, _collect: Collect) -> Result<AnyOutput, CmdExecuteError> {
create_workspace(input.path)
.await
.map_err(JVWorkspaceOperationErrorConverter::to_exec_error)?;
diff --git a/src/cmds/cmd/workspace_init.rs b/src/cmds/cmd/workspace_init.rs
index 543c4db..c77a437 100644
--- a/src/cmds/cmd/workspace_init.rs
+++ b/src/cmds/cmd/workspace_init.rs
@@ -7,7 +7,7 @@ use crate::{
},
systems::{
cmd::{
- cmd_system::JVCommandContext,
+ cmd_system::{AnyOutput, JVCommandContext},
errors::{CmdExecuteError, CmdPrepareError},
},
helpdoc::helpdoc_viewer,
@@ -15,7 +15,6 @@ use crate::{
};
use cmd_system_macros::exec;
use just_enough_vcs::system::workspace::func::create_workspace_here;
-use std::any::TypeId;
pub struct JVWorkspaceInitCommand;
type Cmd = JVWorkspaceInitCommand;
@@ -37,10 +36,7 @@ async fn collect(_args: &Arg, _ctx: &JVCommandContext) -> Result<Collect, CmdPre
}
#[exec]
-async fn exec(
- _input: In,
- _collect: Collect,
-) -> Result<(Box<dyn std::any::Any + Send + 'static>, TypeId), CmdExecuteError> {
+async fn exec(_input: In, _collect: Collect) -> Result<AnyOutput, CmdExecuteError> {
create_workspace_here()
.await
.map_err(JVWorkspaceOperationErrorConverter::to_exec_error)?;
diff --git a/src/cmds/converter/workspace_operation_error.rs b/src/cmds/converter/workspace_operation_error.rs
index f5f9d17..f2f71d0 100644
--- a/src/cmds/converter/workspace_operation_error.rs
+++ b/src/cmds/converter/workspace_operation_error.rs
@@ -26,6 +26,9 @@ impl JVWorkspaceOperationErrorConverter {
WorkspaceOperationError::DataApply(data_apply_error) => {
CmdExecuteError::Error(format!("Data apply error: {}", data_apply_error))
}
+ WorkspaceOperationError::IDAliasError(id_alias_error) => {
+ CmdExecuteError::Error(format!("ID alias error: {}", id_alias_error))
+ }
}
}
}
diff --git a/src/systems/cmd/cmd_system.rs b/src/systems/cmd/cmd_system.rs
index 3ae4d5e..7272c9e 100644
--- a/src/systems/cmd/cmd_system.rs
+++ b/src/systems/cmd/cmd_system.rs
@@ -9,11 +9,13 @@ use crate::{
},
};
use std::{
- any::{Any, TypeId, type_name},
+ any::{TypeId, type_name},
collections::HashMap,
future::Future,
};
+pub type AnyOutput = (Box<dyn std::any::Any + Send + 'static>, TypeId);
+
pub struct JVCommandContext {
pub help: bool,
pub confirmed: bool,
@@ -93,8 +95,7 @@ where
fn process(
args: Vec<String>,
ctx: JVCommandContext,
- ) -> impl Future<Output = Result<(Box<dyn Any + Send + 'static>, TypeId), CmdProcessError>> + Send
- {
+ ) -> impl Future<Output = Result<AnyOutput, CmdProcessError>> + Send {
async move {
let mut full_args = vec!["jv".to_string()];
@@ -173,7 +174,7 @@ where
fn exec(
input: Input,
collect: Collect,
- ) -> impl Future<Output = Result<(Box<dyn Any + Send + 'static>, TypeId), CmdExecuteError>> + Send;
+ ) -> impl Future<Output = Result<AnyOutput, CmdExecuteError>> + Send;
/// Get output type mapping
fn get_output_type_mapping() -> HashMap<String, TypeId>;
diff --git a/src/systems/cmd/macros.rs b/src/systems/cmd/macros.rs
index e9af1ac..5763961 100644
--- a/src/systems/cmd/macros.rs
+++ b/src/systems/cmd/macros.rs
@@ -12,15 +12,21 @@
/// Then paste the following content into your code
///
/// ```ignore
-/// use std::any::TypeId;
-/// use cmd_system_macros::exec;
/// use crate::{
/// cmd_output,
-/// systems::cmd::{
-/// cmd_system::JVCommandContext,
-/// errors::{CmdExecuteError, CmdPrepareError},
+/// cmds::{
+/// arg::empty::JVEmptyArgument, collect::empty::JVEmptyCollect, r#in::empty::JVEmptyInput,
+/// out::none::JVNoneOutput,
+/// },
+/// systems::{
+/// cmd::{
+/// cmd_system::{AnyOutput, JVCommandContext},
+/// errors::{CmdExecuteError, CmdPrepareError},
+/// },
+/// helpdoc::helpdoc_viewer,
/// },
/// };
+/// use cmd_system_macros::exec;
///
/// /// Define command type
/// /// Names should match the file name in the following format:
@@ -36,86 +42,86 @@
/// /// #[derive(Parser, Debug)]
/// /// pub struct JVCustomArgument;
/// /// ```
-/// type Arg = JVCustomArgument;
+/// type Arg = JVEmptyArgument;
///
/// /// Specify InputData
/// /// ```ignore
/// /// pub struct JVCustomInput;
/// /// ```
-/// type In = JVCustomInput;
+/// type In = JVEmptyInput;
///
/// /// Specify CollectData
/// /// ```ignore
/// /// pub struct JVCustomCollect;
/// /// ```
-/// type Collect = JVCustomCollect;
+/// type Collect = JVEmptyCollect;
///
/// /// Return a string, rendered when the user needs help (command specifies `--help` or syntax error)
/// async fn help_str() -> String {
-/// todo!()
+/// // Write your documentation in `./resources/helpdoc`
+/// // Use the format `title.lang.md`
+/// helpdoc_viewer::display("commands/custom_command").await;
+/// String::new()
/// }
///
/// /// Preparation phase, preprocess user input and convert to a data format friendly for the execution phase
-/// async fn prepare(args: &Arg, ctx: &JVCommandContext) -> Result<In, CmdPrepareError> {
-/// todo!()
+/// async fn prepare(_args: &Arg, _ctx: &JVCommandContext) -> Result<In, CmdPrepareError> {
+/// Ok(JVEmptyInput)
/// }
///
/// /// Collect necessary local information for execution
-/// async fn collect(args: &Arg, ctx: &JVCommandContext) -> Result<Collect, CmdPrepareError> {
-/// todo!()
+/// async fn collect(_args: &Arg, _ctx: &JVCommandContext) -> Result<Collect, CmdPrepareError> {
+/// Ok(JVEmptyCollect)
/// }
///
/// /// Execution phase, call core layer or other custom logic
/// #[exec]
-/// async fn exec(
-/// input: In,
-/// collect: Collect,
-/// ) -> Result<(Box<dyn std::any::Any + Send + 'static>, TypeId), CmdExecuteError> {
-/// todo!();
-///
-/// // Use the following method to return results
-/// cmd_output!(JVCustomOutput => output)
+/// async fn exec(_input: In, _collect: Collect) -> Result<AnyOutput, CmdExecuteError> {
+/// cmd_output!(JVNoneOutput => JVNoneOutput)
/// }
/// ```
///
/// Of course, you can also use the comment-free version
///
/// ```ignore
-/// use std::any::TypeId;
-/// use cmd_system_macros::exec;
/// use crate::{
/// cmd_output,
-/// systems::cmd::{
-/// cmd_system::JVCommandContext,
-/// errors::{CmdExecuteError, CmdPrepareError},
+/// cmds::{
+/// arg::empty::JVEmptyArgument, collect::empty::JVEmptyCollect, r#in::empty::JVEmptyInput,
+/// out::none::JVNoneOutput,
+/// },
+/// systems::{
+/// cmd::{
+/// cmd_system::{AnyOutput, JVCommandContext},
+/// errors::{CmdExecuteError, CmdPrepareError},
+/// },
+/// helpdoc::helpdoc_viewer,
/// },
/// };
+/// use cmd_system_macros::exec;
///
/// pub struct JVCustomCommand;
/// type Cmd = JVCustomCommand;
-/// type Arg = JVCustomArgument;
-/// type In = JVCustomInput;
-/// type Collect = JVCustomCollect;
+/// type Arg = JVEmptyArgument;
+/// type In = JVEmptyInput;
+/// type Collect = JVEmptyCollect;
///
/// async fn help_str() -> String {
-/// todo!()
+/// helpdoc_viewer::display("commands/custom_command").await;
+/// String::new()
/// }
///
-/// async fn prepare(args: &Arg, ctx: &JVCommandContext) -> Result<In, CmdPrepareError> {
-/// todo!()
+/// async fn prepare(_args: &Arg, _ctx: &JVCommandContext) -> Result<In, CmdPrepareError> {
+/// Ok(JVEmptyInput)
/// }
///
-/// async fn collect(args: &Arg, ctx: &JVCommandContext) -> Result<Collect, CmdPrepareError> {
-/// todo!()
+/// async fn collect(_args: &Arg, _ctx: &JVCommandContext) -> Result<Collect, CmdPrepareError> {
+/// Ok(JVEmptyCollect)
/// }
///
/// #[exec]
-/// async fn exec(
-/// input: In,
-/// collect: Collect,
-/// ) -> Result<(Box<dyn std::any::Any + Send + 'static>, TypeId), CmdExecuteError> {
-/// todo!();
-/// cmd_output!(JVCustomOutput => output)
+/// async fn exec(_input: In, _collect: Collect) -> Result<AnyOutput, CmdExecuteError> {
+/// cmd_output!(JVNoneOutput => JVNoneOutput)
/// }
/// ```
macro_rules! command_template {
@@ -143,7 +149,7 @@ macro_rules! command_template {
input: In,
collect: Collect,
) -> Result<
- (Box<dyn std::any::Any + Send + 'static>, std::any::TypeId),
+ crate::systems::cmd::cmd_system::AnyOutput,
$crate::systems::cmd::errors::CmdExecuteError,
> {
exec(input, collect).await