From bfb8c076bea255c0b9a6afe9d6bd4d603afa5804 Mon Sep 17 00:00:00 2001 From: Fabian Stamm Date: Wed, 28 May 2025 15:54:53 +0200 Subject: [PATCH] Add Context to Rust service --- libjrpc/src/targets/rust.rs | 30 +++++++++++++++----------- libjrpc/templates/Rust/Cargo.toml | 14 ++++++------ libjrpc/templates/Rust/src/lib.rs | 36 ++++++++++++++++++------------- 3 files changed, 46 insertions(+), 34 deletions(-) diff --git a/libjrpc/src/targets/rust.rs b/libjrpc/src/targets/rust.rs index ed580c2..44715cb 100644 --- a/libjrpc/src/targets/rust.rs +++ b/libjrpc/src/targets/rust.rs @@ -146,8 +146,9 @@ impl RustCompiler { f.a0("#[async_trait]"); f.a0(format!("pub trait {} {{", definition.name)); + f.a1("type Context: Clone + Sync + Send + 'static;"); for method in definition.methods.iter() { - let params = method + let mut params = method .inputs .iter() .map(|arg| { @@ -157,8 +158,9 @@ impl RustCompiler { Self::type_to_rust_ext(&arg.typ) ) }) - .collect::>() - .join(", "); + .collect::>(); + params.push("ctx: Self::Context".to_string()); + let params = params.join(", "); let ret = method .output @@ -179,17 +181,20 @@ impl RustCompiler { f.a0("}"); f.a0(""); - f.a0(format!("pub struct {}Handler {{", definition.name)); + f.a0(format!("pub struct {}Handler {{", definition.name)); f.a1(format!( - "implementation: Box,", + "implementation: Box + Sync + Send + 'static>,", definition.name )); f.a0("}"); f.a0(""); - f.a0(format!("impl {}Handler {{", definition.name)); + f.a0(format!( + "impl {}Handler {{", + definition.name + )); f.a1(format!( - "pub fn new(implementation: Box) -> Arc {{", + "pub fn new(implementation: Box + Sync + Send + 'static>) -> Arc {{", definition.name, )); f.a2("Arc::from(Self { implementation })"); @@ -200,9 +205,10 @@ impl RustCompiler { f.a0("#[async_trait]"); f.a0(format!( - "impl JRPCServerService for {}Handler {{", + "impl JRPCServerService for {}Handler {{", definition.name )); + f.a1("type Context = Context;"); f.a1(format!( "fn get_id(&self) -> String {{ \"{}\".to_owned() }} ", definition.name @@ -212,7 +218,7 @@ impl RustCompiler { f.a1("#[allow(non_snake_case)]"); f.a1( - "async fn handle(&self, msg: &JRPCRequest, function: &str) -> Result<(bool, Value)> {", + "async fn handle(&self, msg: &JRPCRequest, function: &str, ctx: Self::Context) -> Result<(bool, Value)> {", ); f.a2("match function {"); @@ -225,7 +231,7 @@ impl RustCompiler { )); if method.inputs.len() < 1 { f.a5(format!( - "let res = self.implementation.{}().await?;", + "let res = self.implementation.{}(ctx).await?;", method.name )); f.a5("Ok((true, serde_json::to_value(res)?))"); @@ -249,7 +255,7 @@ impl RustCompiler { ), ); } - f.a5(").await?;"); + f.a5(",ctx).await?;"); if let Some(_output) = &method.output { f.a5("Ok((true, serde_json::to_value(res)?))"); @@ -277,7 +283,7 @@ impl RustCompiler { ), ); } - f.a5(").await?;"); + f.a5(", ctx).await?;"); if let Some(_output) = &method.output { f.a5("Ok((true, serde_json::to_value(res)?))"); } else { diff --git a/libjrpc/templates/Rust/Cargo.toml b/libjrpc/templates/Rust/Cargo.toml index 84d3258..2506248 100644 --- a/libjrpc/templates/Rust/Cargo.toml +++ b/libjrpc/templates/Rust/Cargo.toml @@ -6,10 +6,10 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -int-enum = { version = "0.5.0", features = ["serde", "convert"] } -serde = { version = "1.0.147", features = ["derive"] } -serde_json = "1.0.88" -nanoid = "0.4.0" -tokio = { version = "1.22.0", features = ["full"] } -log = "0.4.17" -async-trait = "0.1.59" +int-enum = { version = "0.5", features = ["serde", "convert"] } +serde = { version = "1", features = ["derive"] } +serde_json = "1" +nanoid = "0.4" +tokio = { version = "1", features = ["full"] } +log = "0.4" +async-trait = "0.1" diff --git a/libjrpc/templates/Rust/src/lib.rs b/libjrpc/templates/Rust/src/lib.rs index 2dc2f96..4e2511d 100644 --- a/libjrpc/templates/Rust/src/lib.rs +++ b/libjrpc/templates/Rust/src/lib.rs @@ -105,21 +105,27 @@ impl JRPCClient { } #[async_trait::async_trait] -pub trait JRPCServerService: Send + Sync + 'static { +pub trait JRPCServerService: Send + Sync { + type Context; fn get_id(&self) -> String; - async fn handle(&self, request: &JRPCRequest, function: &str) -> Result<(bool, Value)>; + async fn handle( + &self, + request: &JRPCRequest, + function: &str, + ctx: Self::Context, + ) -> Result<(bool, Value)>; } -pub type JRPCServiceHandle = Arc; +pub type JRPCServiceHandle = Arc>; #[derive(Clone)] -pub struct JRPCSession { - server: JRPCServer, +pub struct JRPCSession { + server: JRPCServer, message_sender: Sender, } -impl JRPCSession { - pub fn new(server: JRPCServer, sender: Sender) -> JRPCSession { +impl JRPCSession { + pub fn new(server: JRPCServer, sender: Sender) -> Self { JRPCSession { server, message_sender: sender, @@ -148,7 +154,7 @@ impl JRPCSession { } } - pub fn handle_request(&self, request: JRPCRequest) -> () { + pub fn handle_request(&self, request: JRPCRequest, ctx: Context) -> () { let session = self.clone(); tokio::task::spawn(async move { info!("Received request: {}", request.method); @@ -163,7 +169,7 @@ impl JRPCSession { let service = session.server.services.get(service); if let Some(service) = service { - let result = service.handle(&request, function).await; + let result = service.handle(&request, function, ctx).await; match result { Ok((is_send, result)) => { if is_send && request.id.is_some() { @@ -204,23 +210,23 @@ impl JRPCSession { } #[derive(Clone)] -pub struct JRPCServer { - services: HashMap, +pub struct JRPCServer { + services: HashMap>, } -impl JRPCServer { - pub fn new() -> JRPCServer { +impl JRPCServer { + pub fn new() -> Self { JRPCServer { services: HashMap::new(), } } - pub fn add_service(&mut self, service: JRPCServiceHandle) -> () { + pub fn add_service(&mut self, service: JRPCServiceHandle) -> () { let id = service.get_id(); self.services.insert(id, service); } - pub fn get_session(&self, sender: Sender) -> JRPCSession { + pub fn get_session(&self, sender: Sender) -> JRPCSession { JRPCSession::new(self.clone(), sender) } }