Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add macro attr with_extensions #1380

Merged
merged 4 commits into from
Jun 3, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/examples/jsonrpsee_as_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ use jsonrpsee::core::async_trait;
use jsonrpsee::http_client::HttpClientBuilder;
use jsonrpsee::proc_macros::rpc;
use jsonrpsee::server::middleware::rpc::{ResponseFuture, RpcServiceBuilder, RpcServiceT};
use jsonrpsee::server::{stop_channel, Extensions, ServerHandle, StopHandle, TowerServiceBuilder};
use jsonrpsee::server::{stop_channel, ServerHandle, StopHandle, TowerServiceBuilder};
use jsonrpsee::types::{ErrorObject, ErrorObjectOwned, Request};
use jsonrpsee::ws_client::{HeaderValue, WsClientBuilder};
use jsonrpsee::{MethodResponse, Methods};
Expand Down Expand Up @@ -100,7 +100,7 @@ pub trait Rpc {

#[async_trait]
impl RpcServer for () {
async fn trusted_call(&self, _ext: &Extensions) -> Result<String, ErrorObjectOwned> {
async fn trusted_call(&self) -> Result<String, ErrorObjectOwned> {
Ok("mysecret".to_string())
}
}
Expand Down
4 changes: 2 additions & 2 deletions examples/examples/jsonrpsee_server_low_level_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ use jsonrpsee::server::{
};
use jsonrpsee::types::{ErrorObject, ErrorObjectOwned, Request};
use jsonrpsee::ws_client::WsClientBuilder;
use jsonrpsee::{Extensions, MethodResponse, Methods};
use jsonrpsee::{MethodResponse, Methods};
use tokio::net::TcpListener;
use tokio::sync::mpsc;
use tokio::sync::Mutex as AsyncMutex;
Expand Down Expand Up @@ -108,7 +108,7 @@ pub trait Rpc {

#[async_trait]
impl RpcServer for () {
async fn say_hello(&self, _ext: &Extensions) -> Result<String, ErrorObjectOwned> {
async fn say_hello(&self) -> Result<String, ErrorObjectOwned> {
Ok("lo".to_string())
}
}
Expand Down
5 changes: 1 addition & 4 deletions examples/examples/proc_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ use jsonrpsee::proc_macros::rpc;
use jsonrpsee::server::{PendingSubscriptionSink, Server, SubscriptionMessage};
use jsonrpsee::types::ErrorObjectOwned;
use jsonrpsee::ws_client::WsClientBuilder;
use jsonrpsee::Extensions;

type ExampleHash = [u8; 32];
type ExampleStorageKey = Vec<u8>;
Expand Down Expand Up @@ -63,7 +62,6 @@ pub struct RpcServerImpl;
impl RpcServer<ExampleHash, ExampleStorageKey> for RpcServerImpl {
async fn storage_keys(
&self,
_ext: &Extensions,
storage_key: ExampleStorageKey,
_hash: Option<ExampleHash>,
) -> Result<Vec<ExampleStorageKey>, ErrorObjectOwned> {
Expand All @@ -73,7 +71,6 @@ impl RpcServer<ExampleHash, ExampleStorageKey> for RpcServerImpl {
async fn subscribe_storage(
&self,
pending: PendingSubscriptionSink,
_ext: &Extensions,
_keys: Option<Vec<ExampleStorageKey>>,
) -> SubscriptionResult {
let sink = pending.accept().await?;
Expand All @@ -83,7 +80,7 @@ impl RpcServer<ExampleHash, ExampleStorageKey> for RpcServerImpl {
Ok(())
}

fn s(&self, pending: PendingSubscriptionSink, _ext: &Extensions, _keys: Option<Vec<ExampleStorageKey>>) {
fn s(&self, pending: PendingSubscriptionSink, _keys: Option<Vec<ExampleStorageKey>>) {
tokio::spawn(async move {
let sink = pending.accept().await.unwrap();
let msg = SubscriptionMessage::from_json(&vec![[0; 32]]).unwrap();
Expand Down
4 changes: 1 addition & 3 deletions examples/examples/proc_macro_bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ use jsonrpsee::proc_macros::rpc;
use jsonrpsee::server::Server;
use jsonrpsee::types::ErrorObjectOwned;
use jsonrpsee::ws_client::WsClientBuilder;
use jsonrpsee::Extensions;

type ExampleHash = [u8; 32];

pub trait Config {
Expand Down Expand Up @@ -62,7 +60,7 @@ pub struct RpcServerImpl;

#[async_trait]
impl RpcServer<ExampleHash> for RpcServerImpl {
fn method(&self, _ext: &Extensions) -> Result<<ExampleHash as Config>::Hash, ErrorObjectOwned> {
fn method(&self) -> Result<<ExampleHash as Config>::Hash, ErrorObjectOwned> {
Ok([0u8; 32])
}
}
Expand Down
4 changes: 2 additions & 2 deletions examples/examples/response_payload_notify_on_response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use jsonrpsee::core::client::ClientT;
use jsonrpsee::proc_macros::rpc;
use jsonrpsee::server::Server;
use jsonrpsee::ws_client::WsClientBuilder;
use jsonrpsee::{rpc_params, Extensions, ResponsePayload};
use jsonrpsee::{rpc_params, ResponsePayload};

#[rpc(client, server, namespace = "state")]
pub trait Rpc {
Expand All @@ -42,7 +42,7 @@ pub trait Rpc {
pub struct RpcServerImpl;

impl RpcServer for RpcServerImpl {
fn storage_keys(&self, _ext: &Extensions) -> ResponsePayload<'static, String> {
fn storage_keys(&self) -> ResponsePayload<'static, String> {
let (rp, rp_future) = ResponsePayload::success("ehheeheh".to_string()).notify_on_completion();

tokio::spawn(async move {
Expand Down
4 changes: 2 additions & 2 deletions examples/examples/server_with_connection_details.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ where
#[rpc(server, client)]
pub trait Rpc {
/// method with connection ID.
#[method(name = "connectionIdMethod")]
#[method(name = "connectionIdMethod", with_extensions)]
async fn method(&self, first_param: usize, second_param: u16) -> Result<u32, ErrorObjectOwned>;

#[subscription(name = "subscribeConnectionId", item = u32)]
#[subscription(name = "subscribeConnectionId", item = u32, with_extensions)]
async fn sub(&self) -> SubscriptionResult;
}

Expand Down
7 changes: 5 additions & 2 deletions proc-macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@ heck = "0.5.0"

[dev-dependencies]
jsonrpsee = { path = "../jsonrpsee", features = ["server", "client-core", "http-client", "ws-client", "macros"] }
trybuild = "1.0"
tokio = { version = "1.16", features = ["rt", "macros"] }
hyper = "1.3"
hyper-util = { version = "0.1.3", features = ["client", "client-legacy"]}
futures-channel = { version = "0.3.14", default-features = false }
futures-util = { version = "0.3.14", default-features = false }
serde_json = "1"
serde = "1"
trybuild = "1.0"
tokio = { version = "1.16", features = ["rt", "macros"] }
tower = "0.4"
12 changes: 6 additions & 6 deletions proc-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,15 +309,15 @@ pub(crate) mod visitor;
/// // Note that the trait name we use is `MyRpcServer`, not `MyRpc`!
/// #[async_trait]
/// impl MyRpcServer for RpcServerImpl {
/// async fn async_method(&self, _ext: &Extensions, _param_a: u8, _param_b: String) -> RpcResult<u16> {
/// async fn async_method(&self, _param_a: u8, _param_b: String) -> RpcResult<u16> {
/// Ok(42)
/// }
///
/// fn sync_method(&self, _ext: &Extensions) -> RpcResult<u16> {
/// fn sync_method(&self) -> RpcResult<u16> {
/// Ok(10)
/// }
///
/// fn blocking_method(&self, _ext: &Extensions) -> RpcResult<u16> {
/// fn blocking_method(&self) -> RpcResult<u16> {
/// // This will block current thread for 1 second, which is fine since we marked
/// // this method as `blocking` above.
/// std::thread::sleep(std::time::Duration::from_millis(1000));
Expand All @@ -326,14 +326,14 @@ pub(crate) mod visitor;
///
/// // The stream API can be used to pipe items from the underlying stream
/// // as subscription responses.
/// async fn sub_override_notif_method(&self, pending: PendingSubscriptionSink, _ext: &Extensions) -> SubscriptionResult {
/// async fn sub_override_notif_method(&self, pending: PendingSubscriptionSink) -> SubscriptionResult {
/// let mut sink = pending.accept().await?;
/// sink.send("Response_A".into()).await?;
/// Ok(())
/// }
///
/// // Send out two values on the subscription.
/// async fn sub(&self, pending: PendingSubscriptionSink, _ext: &Extensions) -> SubscriptionResult {
/// async fn sub(&self, pending: PendingSubscriptionSink) -> SubscriptionResult {
/// let sink = pending.accept().await?;
///
/// let msg1 = SubscriptionMessage::from("Response_A");
Expand All @@ -348,7 +348,7 @@ pub(crate) mod visitor;
/// // If one doesn't want sent out a close message when a subscription terminates or treat
/// // errors as subscription error notifications then it's possible to implement
/// // `IntoSubscriptionCloseResponse` for customized behavior.
/// async fn sub_custom_close_msg(&self, pending: PendingSubscriptionSink, _ext: &Extensions) -> CloseResponse {
/// async fn sub_custom_close_msg(&self, pending: PendingSubscriptionSink) -> CloseResponse {
/// let Ok(sink) = pending.accept().await else {
/// return CloseResponse::None;
/// };
Expand Down
99 changes: 70 additions & 29 deletions proc-macros/src/render_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,12 @@
let docs = &method.docs;
let mut method_sig = method.signature.clone();

let ext_ty = self.jrps_server_item(quote! { Extensions });
// Add `Extension` as the second parameter to the signature.
let ext: syn::FnArg = syn::parse_quote!(ext: &#ext_ty);
method_sig.sig.inputs.insert(1, ext);
if method.with_extensions {
let ext_ty = self.jrps_server_item(quote! { Extensions });
// Add `Extension` as the second parameter to the signature.
let ext: syn::FnArg = syn::parse_quote!(ext: &#ext_ty);
method_sig.sig.inputs.insert(1, ext);
}

quote! {
#docs
Expand All @@ -86,10 +88,12 @@
let mut sub_sig = sub.signature.clone();
sub_sig.sig.inputs.insert(1, subscription_sink);

let ext_ty = self.jrps_server_item(quote! { Extensions });
// Add `Extension` as the third parameter to the signature.
let ext: syn::FnArg = syn::parse_quote!(ext: &#ext_ty);
sub_sig.sig.inputs.insert(2, ext);
if sub.with_extensions {
let ext_ty = self.jrps_server_item(quote! { Extensions });
// Add `Extension` as the third parameter to the signature.
let ext: syn::FnArg = syn::parse_quote!(ext: &#ext_ty);
sub_sig.sig.inputs.insert(2, ext);
}

quote! {
#docs
Expand Down Expand Up @@ -148,22 +152,40 @@
check_name(&rpc_method_name, rust_method_name.span());

if method.signature.sig.asyncness.is_some() {
handle_register_result(quote! {
rpc.register_async_method(#rpc_method_name, |params, context, ext| async move {
#parsing
#into_response::into_response(context.as_ref().#rust_method_name(&ext, #params_seq).await)
if method.with_extensions {
handle_register_result(quote! {
rpc.register_async_method(#rpc_method_name, |params, context, ext| async move {
#parsing
#into_response::into_response(context.as_ref().#rust_method_name(&ext, #params_seq).await)
})
})
})
} else {
handle_register_result(quote! {
rpc.register_async_method(#rpc_method_name, |params, context, _| async move {
#parsing
#into_response::into_response(context.as_ref().#rust_method_name(#params_seq).await)
})
})
}
} else {
let register_kind =
if method.blocking { quote!(register_blocking_method) } else { quote!(register_method) };

handle_register_result(quote! {
rpc.#register_kind(#rpc_method_name, |params, context, ext| {
#parsing
#into_response::into_response(context.#rust_method_name(&ext, #params_seq))
if method.with_extensions {
handle_register_result(quote! {
rpc.#register_kind(#rpc_method_name, |params, context, ext| {
#parsing
#into_response::into_response(context.#rust_method_name(&ext, #params_seq))
})
})
})
} else {
handle_register_result(quote! {
rpc.#register_kind(#rpc_method_name, |params, context, _| {
#parsing
#into_response::into_response(context.#rust_method_name(#params_seq))
})
})
}
}
})
.collect::<Vec<_>>();
Expand Down Expand Up @@ -200,21 +222,40 @@
};

if sub.signature.sig.asyncness.is_some() {
handle_register_result(quote! {
rpc.register_subscription(#rpc_sub_name, #rpc_notif_name, #rpc_unsub_name, |params, mut pending, context, ext| async move {
#parsing
#into_sub_response::into_response(context.as_ref().#rust_method_name(pending, &ext, #params_seq).await)
if sub.with_extensions {
handle_register_result(quote! {
rpc.register_subscription(#rpc_sub_name, #rpc_notif_name, #rpc_unsub_name, |params, mut pending, context, ext| async move {
#parsing
#into_sub_response::into_response(context.as_ref().#rust_method_name(pending, &ext, #params_seq).await)
})
})
})
} else {
handle_register_result(quote! {
rpc.register_subscription(#rpc_sub_name, #rpc_notif_name, #rpc_unsub_name, |params, mut pending, context, _| async move {
#parsing
#into_sub_response::into_response(context.as_ref().#rust_method_name(pending, #params_seq).await)
})
})
}
} else {
handle_register_result(quote! {
rpc.register_subscription_raw(#rpc_sub_name, #rpc_notif_name, #rpc_unsub_name, |params, mut pending, context, ext| {
#parsing
let _ = context.as_ref().#rust_method_name(pending, &ext, #params_seq);
#sub_err::None
if sub.with_extensions {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you collapse the if into else if following the recommendation from clippy, otherwise LGTM

handle_register_result(quote! {
rpc.register_subscription_raw(#rpc_sub_name, #rpc_notif_name, #rpc_unsub_name, |params, mut pending, context, ext| {
#parsing
let _ = context.as_ref().#rust_method_name(pending, &ext, #params_seq);
#sub_err::None
})
})
})
} else {
handle_register_result(quote! {
rpc.register_subscription_raw(#rpc_sub_name, #rpc_notif_name, #rpc_unsub_name, |params, mut pending, context, _| {
#parsing
let _ = context.as_ref().#rust_method_name(pending, #params_seq);
#sub_err::None
})
})
}
}

Check warning on line 258 in proc-macros/src/render_server.rs

View workflow job for this annotation

GitHub Actions / clippy

this `else { if .. }` block can be collapsed

warning: this `else { if .. }` block can be collapsed --> proc-macros/src/render_server.rs:240:12 | 240 | } else { | ________________________^ 241 | | if sub.with_extensions { 242 | | handle_register_result(quote! { 243 | | rpc.register_subscription_raw(#rpc_sub_name, #rpc_notif_name, #rpc_unsub_name, |params, mut ... ... | 257 | | } 258 | | } | |_________________^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_else_if = note: `#[warn(clippy::collapsible_else_if)]` on by default help: collapse nested if block | 240 ~ } else if sub.with_extensions { 241 ~ handle_register_result(quote! { 242 ~ rpc.register_subscription_raw(#rpc_sub_name, #rpc_notif_name, #rpc_unsub_name, |params, mut pending, context, ext| { 243 ~ #parsing 244 ~ let _ = context.as_ref().#rust_method_name(pending, &ext, #params_seq); 245 ~ #sub_err::None 246 ~ }) 247 ~ }) 248 ~ } else { 249 ~ handle_register_result(quote! { 250 ~ rpc.register_subscription_raw(#rpc_sub_name, #rpc_notif_name, #rpc_unsub_name, |params, mut pending, context, _| { 251 ~ #parsing 252 ~ let _ = context.as_ref().#rust_method_name(pending, #params_seq); 253 ~ #sub_err::None 254 ~ }) 255 ~ }) 256 ~ } |

Check warning on line 258 in proc-macros/src/render_server.rs

View workflow job for this annotation

GitHub Actions / clippy

this `else { if .. }` block can be collapsed

warning: this `else { if .. }` block can be collapsed --> proc-macros/src/render_server.rs:240:12 | 240 | } else { | ________________________^ 241 | | if sub.with_extensions { 242 | | handle_register_result(quote! { 243 | | rpc.register_subscription_raw(#rpc_sub_name, #rpc_notif_name, #rpc_unsub_name, |params, mut ... ... | 257 | | } 258 | | } | |_________________^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_else_if = note: `#[warn(clippy::collapsible_else_if)]` on by default help: collapse nested if block | 240 ~ } else if sub.with_extensions { 241 ~ handle_register_result(quote! { 242 ~ rpc.register_subscription_raw(#rpc_sub_name, #rpc_notif_name, #rpc_unsub_name, |params, mut pending, context, ext| { 243 ~ #parsing 244 ~ let _ = context.as_ref().#rust_method_name(pending, &ext, #params_seq); 245 ~ #sub_err::None 246 ~ }) 247 ~ }) 248 ~ } else { 249 ~ handle_register_result(quote! { 250 ~ rpc.register_subscription_raw(#rpc_sub_name, #rpc_notif_name, #rpc_unsub_name, |params, mut pending, context, _| { 251 ~ #parsing 252 ~ let _ = context.as_ref().#rust_method_name(pending, #params_seq); 253 ~ #sub_err::None 254 ~ }) 255 ~ }) 256 ~ } |

Check warning on line 258 in proc-macros/src/render_server.rs

View workflow job for this annotation

GitHub Actions / clippy

this `else { if .. }` block can be collapsed

warning: this `else { if .. }` block can be collapsed --> proc-macros/src/render_server.rs:240:12 | 240 | } else { | ________________________^ 241 | | if sub.with_extensions { 242 | | handle_register_result(quote! { 243 | | rpc.register_subscription_raw(#rpc_sub_name, #rpc_notif_name, #rpc_unsub_name, |params, mut ... ... | 257 | | } 258 | | } | |_________________^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_else_if = note: `#[warn(clippy::collapsible_else_if)]` on by default help: collapse nested if block | 240 ~ } else if sub.with_extensions { 241 ~ handle_register_result(quote! { 242 ~ rpc.register_subscription_raw(#rpc_sub_name, #rpc_notif_name, #rpc_unsub_name, |params, mut pending, context, ext| { 243 ~ #parsing 244 ~ let _ = context.as_ref().#rust_method_name(pending, &ext, #params_seq); 245 ~ #sub_err::None 246 ~ }) 247 ~ }) 248 ~ } else { 249 ~ handle_register_result(quote! { 250 ~ rpc.register_subscription_raw(#rpc_sub_name, #rpc_notif_name, #rpc_unsub_name, |params, mut pending, context, _| { 251 ~ #parsing 252 ~ let _ = context.as_ref().#rust_method_name(pending, #params_seq); 253 ~ #sub_err::None 254 ~ }) 255 ~ }) 256 ~ } |
})
.collect::<Vec<_>>();

Expand Down
34 changes: 29 additions & 5 deletions proc-macros/src/rpc_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,17 +92,19 @@ pub struct RpcMethod {
pub returns: Option<syn::Type>,
pub signature: syn::TraitItemFn,
pub aliases: Vec<String>,
pub with_extensions: bool,
}

impl RpcMethod {
pub fn from_item(attr: Attribute, mut method: syn::TraitItemFn) -> syn::Result<Self> {
let [aliases, blocking, name, param_kind] =
AttributeMeta::parse(attr)?.retain(["aliases", "blocking", "name", "param_kind"])?;
let [aliases, blocking, name, param_kind, with_extensions] =
AttributeMeta::parse(attr)?.retain(["aliases", "blocking", "name", "param_kind", "with_extensions"])?;

let aliases = parse_aliases(aliases)?;
let blocking = optional(blocking, Argument::flag)?.is_some();
let name = name?.string()?;
let param_kind = parse_param_kind(param_kind)?;
let with_extensions = optional(with_extensions, Argument::flag)?.is_some();

let docs = extract_doc_comments(&method.attrs);
let deprecated = match find_attr(&method.attrs, "deprecated") {
Expand Down Expand Up @@ -144,7 +146,18 @@ impl RpcMethod {
// We've analyzed attributes and don't need them anymore.
method.attrs.clear();

Ok(Self { aliases, blocking, name, params, param_kind, returns, signature: method, docs, deprecated })
Ok(Self {
aliases,
blocking,
name,
params,
param_kind,
returns,
signature: method,
docs,
deprecated,
with_extensions,
})
}
}

Expand All @@ -166,12 +179,21 @@ pub struct RpcSubscription {
pub signature: syn::TraitItemFn,
pub aliases: Vec<String>,
pub unsubscribe_aliases: Vec<String>,
pub with_extensions: bool,
}

impl RpcSubscription {
pub fn from_item(attr: syn::Attribute, mut sub: syn::TraitItemFn) -> syn::Result<Self> {
let [aliases, item, name, param_kind, unsubscribe, unsubscribe_aliases] = AttributeMeta::parse(attr)?
.retain(["aliases", "item", "name", "param_kind", "unsubscribe", "unsubscribe_aliases"])?;
let [aliases, item, name, param_kind, unsubscribe, unsubscribe_aliases, with_extensions] =
AttributeMeta::parse(attr)?.retain([
"aliases",
"item",
"name",
"param_kind",
"unsubscribe",
"unsubscribe_aliases",
"with_extensions",
])?;

let aliases = parse_aliases(aliases)?;
let map = name?.value::<NameMapping>()?;
Expand All @@ -180,6 +202,7 @@ impl RpcSubscription {
let item = item?.value()?;
let param_kind = parse_param_kind(param_kind)?;
let unsubscribe_aliases = parse_aliases(unsubscribe_aliases)?;
let with_extensions = optional(with_extensions, Argument::flag)?.is_some();

let docs = extract_doc_comments(&sub.attrs);
let unsubscribe = match parse_subscribe(unsubscribe)? {
Expand Down Expand Up @@ -218,6 +241,7 @@ impl RpcSubscription {
signature: sub,
aliases,
docs,
with_extensions,
})
}
}
Expand Down
Loading
Loading