diff --git a/Cargo.toml b/Cargo.toml index 11b908fac0..b5553efab9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ members = [ "test-utils", "tests", "tests/wasm-tests", + "tests/proc-macro-core", "types", ] resolver = "2" diff --git a/core/src/lib.rs b/core/src/lib.rs index 0f7ddba510..4c5ed868fa 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -75,6 +75,11 @@ pub mod __reexports { pub use async_trait::async_trait; pub use serde; pub use serde_json; + + // Needed for the params parsing in the proc macro API. + cfg_client_or_server! { + pub use tokio; + } } pub use beef::Cow; diff --git a/core/src/macros.rs b/core/src/macros.rs index e983079f32..b048a7b646 100644 --- a/core/src/macros.rs +++ b/core/src/macros.rs @@ -20,6 +20,15 @@ macro_rules! cfg_server { }; } +macro_rules! cfg_client_or_server { + ($($item:item)*) => { + $( + #[cfg(any(feature = "client", feature = "server"))] + $item + )* + } +} + macro_rules! cfg_http_helpers { ($($item:item)*) => { cfg_feature!("http-helpers", $($item)*); diff --git a/proc-macros/src/render_server.rs b/proc-macros/src/render_server.rs index 2be84da7c8..9fcd085028 100644 --- a/proc-macros/src/render_server.rs +++ b/proc-macros/src/render_server.rs @@ -316,7 +316,7 @@ impl RpcDescription { let tracing = self.jrps_server_item(quote! { tracing }); let sub_err = self.jrps_server_item(quote! { SubscriptionCloseResponse }); let response_payload = self.jrps_server_item(quote! { ResponsePayload }); - let tokio = self.jrps_server_item(quote! { tokio }); + let tokio = self.jrps_server_item(quote! { core::__reexports::tokio }); // Code to decode sequence of parameters from a JSON array. let decode_array = { diff --git a/tests/proc-macro-core/Cargo.toml b/tests/proc-macro-core/Cargo.toml new file mode 100644 index 0000000000..7178301bbb --- /dev/null +++ b/tests/proc-macro-core/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "jsonrpsee-proc-macro-core" +description = "Test crate for the proc-macro API to make sure that it compiles with the core features" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true +publish = false + +[dependencies] +jsonrpsee = { path = "../../jsonrpsee", features = ["server-core", "client-core", "macros"] } +serde = "1.0" \ No newline at end of file diff --git a/tests/proc-macro-core/src/lib.rs b/tests/proc-macro-core/src/lib.rs new file mode 100644 index 0000000000..b98efa8eda --- /dev/null +++ b/tests/proc-macro-core/src/lib.rs @@ -0,0 +1,73 @@ +//! Test module for the proc-macro API to make sure that it compiles with the core features. + +use jsonrpsee::core::{async_trait, SubscriptionResult}; +use jsonrpsee::proc_macros::rpc; +use jsonrpsee::types::ErrorObjectOwned; +use jsonrpsee::{ConnectionDetails, PendingSubscriptionSink, SubscriptionMessage}; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Serialize, Deserialize)] +pub enum PubSubKind { + A, + B, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct PubSubParams { + params: String, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct PubSubItem { + result: String, +} + +#[rpc(client, server)] +pub trait Api { + #[method(name = "sync_call")] + fn sync_call(&self, a: String) -> Result; + + #[method(name = "async_call")] + async fn async_call(&self, a: String) -> Result; + + #[subscription(name = "subscribe", item = PubSubItem)] + async fn sub(&self, kind: PubSubKind, p: PubSubParams) -> SubscriptionResult; + + #[subscription(name = "subscribeSync", item = String)] + fn sync_sub(&self, a: String) -> SubscriptionResult; + + #[method(name = "blocking", blocking)] + fn blocking_method(&self, a: String) -> Result; + + #[method(name = "raw", raw_method)] + async fn raw(&self, a: String) -> Result; +} + +#[async_trait] +impl ApiServer for () { + fn sync_call(&self, _: String) -> Result { + Ok("sync_call".to_string()) + } + + async fn async_call(&self, _: String) -> Result { + Ok("async_call".to_string()) + } + + async fn sub(&self, pending: PendingSubscriptionSink, _: PubSubKind, _: PubSubParams) -> SubscriptionResult { + let sink = pending.accept().await?; + sink.send(SubscriptionMessage::from("msg")).await?; + Ok(()) + } + + fn sync_sub(&self, _: PendingSubscriptionSink, _: String) -> SubscriptionResult { + Ok(()) + } + + fn blocking_method(&self, _: String) -> Result { + Ok(42) + } + + async fn raw(&self, _: ConnectionDetails, _: String) -> Result { + Ok(42) + } +}