Skip to content

Commit

Permalink
fix(proc macros): subscriptions must return result (#455)
Browse files Browse the repository at this point in the history
Similar to #435 that adds the same restrictions to subscriptions too.
To avoid having faulty trait bounds on when the subcription actually returns Result.
  • Loading branch information
niklasad1 authored Sep 9, 2021
1 parent b6d93d2 commit d828e26
Show file tree
Hide file tree
Showing 14 changed files with 44 additions and 57 deletions.
10 changes: 7 additions & 3 deletions examples/proc_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ where

/// Subscription that takes a `StorageKey` as input and produces a `Vec<Hash>`.
#[subscription(name = "subscribeStorage", item = Vec<Hash>)]
fn subscribe_storage(&self, keys: Option<Vec<StorageKey>>);
fn subscribe_storage(&self, keys: Option<Vec<StorageKey>>) -> Result<(), Error>;
}

pub struct RpcServerImpl;
Expand All @@ -61,8 +61,12 @@ impl RpcServer<ExampleHash, ExampleStorageKey> for RpcServerImpl {
Ok(vec![storage_key])
}

fn subscribe_storage(&self, mut sink: SubscriptionSink, _keys: Option<Vec<ExampleStorageKey>>) {
sink.send(&vec![[0; 32]]).unwrap();
fn subscribe_storage(
&self,
mut sink: SubscriptionSink,
_keys: Option<Vec<ExampleStorageKey>>,
) -> Result<(), Error> {
sink.send(&vec![[0; 32]])
}
}

Expand Down
2 changes: 1 addition & 1 deletion proc-macros/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ fn find_jsonrpsee_crate(http_name: &str, ws_name: &str) -> Result<proc_macro2::T
/// fn call(&self, a: A) -> JsonRpcResult<B>;
///
/// #[subscription(name = "sub", item = Vec<C>)]
/// fn sub(&self);
/// fn sub(&self) -> JsonRpcResult<()>;
/// }
/// ```
///
Expand Down
8 changes: 4 additions & 4 deletions proc-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ pub(crate) mod visitor;
/// fn sync_method(&self) -> JsonRpcResult<u16>;
///
/// #[subscription(name = "sub", item = String)]
/// fn sub(&self);
/// fn sub(&self) -> JsonRpcResult<()>;
/// }
///
/// // Structure that will implement the `MyRpcServer` trait.
Expand All @@ -236,9 +236,9 @@ pub(crate) mod visitor;
/// // We could've spawned a `tokio` future that yields values while our program works,
/// // but for simplicity of the example we will only send two values and then close
/// // the subscription.
/// fn sub(&self, mut sink: SubscriptionSink) {
/// sink.send(&"Response_A").unwrap();
/// sink.send(&"Response_B").unwrap();
/// fn sub(&self, mut sink: SubscriptionSink) -> JsonRpcResult<()> {
/// sink.send(&"Response_A")?;
/// sink.send(&"Response_B")
/// }
/// }
/// }
Expand Down
2 changes: 1 addition & 1 deletion proc-macros/src/render_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ impl RpcDescription {
handle_register_result(quote! {
rpc.register_subscription(#rpc_sub_name, #rpc_unsub_name, |params, sink, context| {
#parsing
Ok(context.as_ref().#rust_method_name(sink, #params_seq))
context.as_ref().#rust_method_name(sink, #params_seq)
})
})
})
Expand Down
3 changes: 0 additions & 3 deletions proc-macros/src/rpc_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,6 @@ impl RpcDescription {
if method.sig.asyncness.is_some() {
return Err(syn::Error::new_spanned(&method, "Subscription methods must not be `async`"));
}
if !matches!(method.sig.output, syn::ReturnType::Default) {
return Err(syn::Error::new_spanned(&method, "Subscription methods must not return anything"));
}

let sub_data = RpcSubscription::from_item(method.clone())?;
subscriptions.push(sub_data);
Expand Down
2 changes: 1 addition & 1 deletion proc-macros/tests/ui/correct/alias_doesnt_use_namespace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pub trait Rpc {
async fn async_method(&self, param_a: u8, param_b: String) -> JsonRpcResult<u16>;

#[subscription(name = "getFood", item = String, aliases = "getFood", unsubscribe_aliases = "unsubscribegetFood")]
fn sub(&self);
fn sub(&self) -> JsonRpcResult<()>;
}

fn main() {}
16 changes: 8 additions & 8 deletions proc-macros/tests/ui/correct/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ pub trait Rpc {
fn sync_method(&self) -> JsonRpcResult<u16>;

#[subscription(name = "sub", item = String)]
fn sub(&self);
fn sub(&self) -> JsonRpcResult<()>;

#[subscription(name = "echo", aliases = "ECHO", item = u32, unsubscribe_aliases = "NotInterested, listenNoMore")]
fn sub_with_params(&self, val: u32);
fn sub_with_params(&self, val: u32) -> JsonRpcResult<()>;
}

pub struct RpcServerImpl;
Expand Down Expand Up @@ -58,14 +58,14 @@ impl RpcServer for RpcServerImpl {
Ok(10u16)
}

fn sub(&self, mut sink: SubscriptionSink) {
sink.send(&"Response_A").unwrap();
sink.send(&"Response_B").unwrap();
fn sub(&self, mut sink: SubscriptionSink) -> JsonRpcResult<()> {
sink.send(&"Response_A")?;
sink.send(&"Response_B")
}

fn sub_with_params(&self, mut sink: SubscriptionSink, val: u32) {
sink.send(&val).unwrap();
sink.send(&val).unwrap();
fn sub_with_params(&self, mut sink: SubscriptionSink, val: u32) -> JsonRpcResult<()> {
sink.send(&val)?;
sink.send(&val)
}
}

Expand Down
8 changes: 4 additions & 4 deletions proc-macros/tests/ui/correct/only_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub trait Rpc {
fn sync_method(&self) -> JsonRpcResult<u16>;

#[subscription(name = "sub", item = String)]
fn sub(&self);
fn sub(&self) -> JsonRpcResult<()>;
}

pub struct RpcServerImpl;
Expand All @@ -29,9 +29,9 @@ impl RpcServer for RpcServerImpl {
Ok(10u16)
}

fn sub(&self, mut sink: SubscriptionSink) {
sink.send(&"Response_A").unwrap();
sink.send(&"Response_B").unwrap();
fn sub(&self, mut sink: SubscriptionSink) -> JsonRpcResult<()> {
sink.send(&"Response_A")?;
sink.send(&"Response_B")
}
}

Expand Down
2 changes: 1 addition & 1 deletion proc-macros/tests/ui/correct/rpc_deny_missing_docs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub trait ApiWithoutDocumentation {

/// Subscription docs.
#[subscription(name = "sub", item = String)]
fn sub(&self);
fn sub(&self) -> jsonrpsee::types::JsonRpcResult<()>;
}

fn main() {}
4 changes: 2 additions & 2 deletions proc-macros/tests/ui/incorrect/sub/sub_conflicting_alias.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use jsonrpsee::proc_macros::rpc;
use jsonrpsee::{proc_macros::rpc, types::JsonRpcResult};

#[rpc(client, server)]
pub trait DuplicatedSubAlias {
#[subscription(name = "alias", item = String, aliases = "hello_is_goodbye", unsubscribe_aliases = "hello_is_goodbye")]
fn async_method(&self);
fn async_method(&self) -> JsonRpcResult<()>;
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: "hello_is_goodbye" is already defined
--> $DIR/sub_conflicting_alias.rs:6:5
|
6 | fn async_method(&self);
6 | fn async_method(&self) -> JsonRpcResult<()>;
| ^^^^^^^^^^^^
10 changes: 0 additions & 10 deletions proc-macros/tests/ui/incorrect/sub/sub_return_type.rs

This file was deleted.

6 changes: 0 additions & 6 deletions proc-macros/tests/ui/incorrect/sub/sub_return_type.stderr

This file was deleted.

26 changes: 14 additions & 12 deletions tests/tests/proc_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ mod rpc_impl {
fn sync_method(&self) -> JsonRpcResult<u16>;

#[subscription(name = "sub", item = String)]
fn sub(&self);
fn sub(&self) -> JsonRpcResult<()>;

#[subscription(name = "echo", aliases = "alias_echo", item = u32)]
fn sub_with_params(&self, val: u32);
fn sub_with_params(&self, val: u32) -> JsonRpcResult<()>;

#[method(name = "params")]
fn params(&self, a: u8, b: &str) -> JsonRpcResult<String> {
Expand Down Expand Up @@ -102,7 +102,7 @@ mod rpc_impl {

/// All head subscription
#[subscription(name = "subscribeAllHeads", item = Header)]
fn subscribe_all_heads(&self, hash: Hash);
fn subscribe_all_heads(&self, hash: Hash) -> JsonRpcResult<()>;
}

/// Trait to ensure that the trait bounds are correct.
Expand All @@ -117,7 +117,7 @@ mod rpc_impl {
pub trait OnlyGenericSubscription<Input, R> {
/// Get header of a relay chain block.
#[subscription(name = "sub", item = Vec<R>)]
fn sub(&self, hash: Input);
fn sub(&self, hash: Input) -> JsonRpcResult<()>;
}

/// Trait to ensure that the trait bounds are correct.
Expand Down Expand Up @@ -154,14 +154,16 @@ mod rpc_impl {
Ok(10u16)
}

fn sub(&self, mut sink: SubscriptionSink) {
sink.send(&"Response_A").unwrap();
sink.send(&"Response_B").unwrap();
fn sub(&self, mut sink: SubscriptionSink) -> JsonRpcResult<()> {
sink.send(&"Response_A")?;
sink.send(&"Response_B")?;
Ok(())
}

fn sub_with_params(&self, mut sink: SubscriptionSink, val: u32) {
sink.send(&val).unwrap();
sink.send(&val).unwrap();
fn sub_with_params(&self, mut sink: SubscriptionSink, val: u32) -> JsonRpcResult<()> {
sink.send(&val)?;
sink.send(&val)?;
Ok(())
}
}

Expand All @@ -174,8 +176,8 @@ mod rpc_impl {

#[async_trait]
impl OnlyGenericSubscriptionServer<String, String> for RpcServerImpl {
fn sub(&self, mut sink: SubscriptionSink, _: String) {
sink.send(&"hello").unwrap();
fn sub(&self, mut sink: SubscriptionSink, _: String) -> JsonRpcResult<()> {
sink.send(&"hello")
}
}
}
Expand Down

0 comments on commit d828e26

Please sign in to comment.