diff options
| author | 魏曹先生 <1992414357@qq.com> | 2025-10-13 11:17:00 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2025-10-13 11:17:00 +0800 |
| commit | 860fb317bca61ce66a2c98df933aa666dae0a43f (patch) | |
| tree | 1aa4440e23b6344097958888aeef231ba4d9e9ba | |
| parent | 635ded4f6815d738dd9b9b711aa4c7cf302d340b (diff) | |
feat: Add JSON-based action invocation to ActionPool
- Extend action_gen macro to generate JSON serialization logic
- Implement generic action processing using JSON text for type-agnostic calls
- Add callback mechanism with action name and arguments in ActionPool
- Update client and server registries to use new callback system
- Improve action system flexibility at the cost of serialization overhead
| -rw-r--r-- | Cargo.lock | 5 | ||||
| -rw-r--r-- | crates/system_action/Cargo.toml | 1 | ||||
| -rw-r--r-- | crates/system_action/action_macros/Cargo.toml | 4 | ||||
| -rw-r--r-- | crates/system_action/action_macros/src/lib.rs | 34 | ||||
| -rw-r--r-- | crates/system_action/src/action_pool.rs | 4 | ||||
| -rw-r--r-- | crates/vcs_actions/src/registry/client_registry.rs | 4 | ||||
| -rw-r--r-- | crates/vcs_actions/src/registry/server_registry.rs | 4 | ||||
| -rw-r--r-- | examples/Cargo.toml | 4 | ||||
| -rw-r--r-- | examples/src/bin/example_action_system.rs | 4 |
9 files changed, 42 insertions, 22 deletions
@@ -8,6 +8,7 @@ version = "0.1.0" dependencies = [ "action_system_macros", "serde", + "serde_json", "tcp_connection", "tokio", ] @@ -18,6 +19,8 @@ version = "0.1.0" dependencies = [ "proc-macro2", "quote", + "serde", + "serde_json", "string_proc", "syn", "tcp_connection", @@ -419,6 +422,8 @@ version = "0.1.0" dependencies = [ "action_system", "cfg_file", + "serde", + "serde_json", "string_proc", "tcp_connection", "tokio", diff --git a/crates/system_action/Cargo.toml b/crates/system_action/Cargo.toml index 120cb34..54ae454 100644 --- a/crates/system_action/Cargo.toml +++ b/crates/system_action/Cargo.toml @@ -9,6 +9,7 @@ action_system_macros = { path = "action_macros" } # Serialization serde = { version = "1.0.219", features = ["derive"] } +serde_json = "1.0.140" # Async & Networking tokio = { version = "1.46.1", features = ["full"] } diff --git a/crates/system_action/action_macros/Cargo.toml b/crates/system_action/action_macros/Cargo.toml index 5ae14fa..869dcde 100644 --- a/crates/system_action/action_macros/Cargo.toml +++ b/crates/system_action/action_macros/Cargo.toml @@ -13,3 +13,7 @@ string_proc = { path = "../../utils/string_proc" } syn = { version = "2.0", features = ["full", "extra-traits"] } quote = "1.0" proc-macro2 = "1.0" + +# Serialization +serde = { version = "1.0.219", features = ["derive"] } +serde_json = "1.0.140" diff --git a/crates/system_action/action_macros/src/lib.rs b/crates/system_action/action_macros/src/lib.rs index 04e974a..683efcb 100644 --- a/crates/system_action/action_macros/src/lib.rs +++ b/crates/system_action/action_macros/src/lib.rs @@ -37,6 +37,9 @@ fn generate_action_struct(input_fn: ItemFn, _is_local: bool) -> proc_macro2::Tok let action_name_ident = &fn_name; + let register_this_action = quote::format_ident!("register_{}", action_name_ident); + let proc_this_action = quote::format_ident!("proc_{}", action_name_ident); + quote! { #[derive(Debug, Clone, Default)] #fn_vis struct #struct_name; @@ -55,22 +58,23 @@ fn generate_action_struct(input_fn: ItemFn, _is_local: bool) -> proc_macro2::Tok } } - impl #struct_name { - #fn_vis fn register_to_pool(pool: &mut action_system::action_pool::ActionPool) { - pool.register::<#struct_name, #arg_type, #return_type>(); - } + #fn_vis fn #register_this_action(pool: &mut action_system::action_pool::ActionPool) { + pool.register::<#struct_name, #arg_type, #return_type>(); + } - #fn_vis async fn process_at_pool<'a>( - pool: &'a action_system::action_pool::ActionPool, - ctx: action_system::action::ActionContext, - #arg_param_name: #arg_type - ) -> Result<#return_type, tcp_connection::error::TcpTargetError> { - pool.process::<#arg_type, #return_type>( - Box::leak(string_proc::snake_case!(stringify!(#action_name_ident)).into_boxed_str()), - ctx, - #arg_param_name - ).await - } + #fn_vis async fn #proc_this_action( + pool: &action_system::action_pool::ActionPool, + ctx: action_system::action::ActionContext, + #arg_param_name: #arg_type + ) -> Result<#return_type, tcp_connection::error::TcpTargetError> { + pool.process::<#arg_type, #return_type>( + Box::leak(string_proc::snake_case!(stringify!(#action_name_ident)).into_boxed_str()), + ctx, + serde_json::to_string(&#arg_param_name) + .map_err(|e| { + tcp_connection::error::TcpTargetError::Serialization(e.to_string()) + })? + ).await } #[allow(dead_code)] diff --git a/crates/system_action/src/action_pool.rs b/crates/system_action/src/action_pool.rs index bc60f7f..a3e82d6 100644 --- a/crates/system_action/src/action_pool.rs +++ b/crates/system_action/src/action_pool.rs @@ -72,7 +72,7 @@ impl ActionPool { &'a self, action_name: &'a str, context: ActionContext, - args: Args, + args_json: String, ) -> Result<Return, TcpTargetError> where Args: serde::de::DeserializeOwned + Send + 'static, @@ -80,6 +80,8 @@ impl ActionPool { { if let Some(action) = self.actions.get(action_name) { let _ = self.exec_on_proc_begin(&context).await?; + let args: Args = serde_json::from_str(&args_json) + .map_err(|e| TcpTargetError::Serialization(format!("Deserialize failed: {}", e)))?; let result = action.process_erased(context, Box::new(args)).await?; let result = *result .downcast::<Return>() diff --git a/crates/vcs_actions/src/registry/client_registry.rs b/crates/vcs_actions/src/registry/client_registry.rs index c32ce5a..d298099 100644 --- a/crates/vcs_actions/src/registry/client_registry.rs +++ b/crates/vcs_actions/src/registry/client_registry.rs @@ -1,11 +1,11 @@ use action_system::{action::ActionContext, action_pool::ActionPool}; use tcp_connection::error::TcpTargetError; -use crate::actions::local_actions::SetUpstreamVaultAction; +use crate::actions::local_actions::register_set_upstream_vault_action; fn register_actions(pool: &mut ActionPool) { // Pool register here - SetUpstreamVaultAction::register_to_pool(pool); + register_set_upstream_vault_action(pool); } pub fn client_action_pool() -> ActionPool { diff --git a/crates/vcs_actions/src/registry/server_registry.rs b/crates/vcs_actions/src/registry/server_registry.rs index bdd6a65..3ecc103 100644 --- a/crates/vcs_actions/src/registry/server_registry.rs +++ b/crates/vcs_actions/src/registry/server_registry.rs @@ -1,9 +1,9 @@ use action_system::action_pool::ActionPool; -use crate::actions::local_actions::SetUpstreamVaultAction; +use crate::actions::local_actions::register_set_upstream_vault_action; pub fn server_action_pool() -> ActionPool { let mut pool = ActionPool::new(); - SetUpstreamVaultAction::register_to_pool(&mut pool); + register_set_upstream_vault_action(&mut pool); pool } diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 3a6cee2..f2442ba 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -19,3 +19,7 @@ action_system = { path = "../crates/system_action" } # Async & Networking tokio = { version = "1.46.1", features = ["full"] } + +# Serialization +serde = { version = "1.0.219", features = ["derive"] } +serde_json = "1.0.140" diff --git a/examples/src/bin/example_action_system.rs b/examples/src/bin/example_action_system.rs index a659eb3..c873a2e 100644 --- a/examples/src/bin/example_action_system.rs +++ b/examples/src/bin/example_action_system.rs @@ -4,9 +4,9 @@ use tcp_connection::error::TcpTargetError; #[tokio::main] async fn main() { let mut pool = ActionPool::new(); - PrintNameAction::register_to_pool(&mut pool); + register_print_name_action(&mut pool); - PrintNameAction::process_at_pool(&pool, ActionContext::local(), "World".to_string()) + proc_print_name_action(&pool, ActionContext::local(), "World".to_string()) .await .unwrap(); } |
