-
Notifications
You must be signed in to change notification settings - Fork 172
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
[proc macros]: support generic type params #436
Changes from 24 commits
faf78f1
351acaf
66640e7
1f91aac
230613e
4ed5b58
f442612
834990e
fbb6f00
6e5bcf1
ab0b2ec
63c48bd
c7ce163
c843a99
f04aeaf
52f61b2
64b33fb
c9b00c8
8bff2e9
fbd9683
9f0b300
3065c04
6971610
6f3fed9
6abda51
d86752a
4c83ecc
6ad7bc2
f8facb2
e197af5
27c3a15
ebd7147
3626e15
ba52568
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,33 +26,40 @@ | |
|
||
use jsonrpsee::{ | ||
proc_macros::rpc, | ||
types::{async_trait, error::Error}, | ||
types::{async_trait, error::Error, Subscription}, | ||
ws_client::WsClientBuilder, | ||
ws_server::{RpcModule, SubscriptionSink, WsServerBuilder}, | ||
ws_server::{SubscriptionSink, WsServerBuilder}, | ||
}; | ||
use std::net::SocketAddr; | ||
|
||
type ExampleHash = [u8; 32]; | ||
type ExampleStorageKey = Vec<u8>; | ||
|
||
#[rpc(server, client, namespace = "state")] | ||
pub trait Rpc { | ||
pub trait Rpc<Hash: std::fmt::Debug, StorageKey> { | ||
/// Async method call example. | ||
#[method(name = "getPairs")] | ||
async fn storage_pairs(&self, prefix: usize, hash: Option<u128>) -> Result<Vec<usize>, Error>; | ||
#[method(name = "getKeys")] | ||
async fn storage_keys(&self, storage_key: StorageKey, hash: Option<Hash>) -> Result<Vec<StorageKey>, Error>; | ||
|
||
/// Subscription that take `Option<Vec<u8>>` as input and produces output `Vec<usize>`. | ||
#[subscription(name = "subscribeStorage", unsub = "unsubscribeStorage", item = Vec<usize>)] | ||
fn subscribe_storage(&self, keys: Option<Vec<u8>>); | ||
/// Subscription that takes a `StorageKey` as input and produces a `Vec<Hash>`. | ||
#[subscription(name = "subscribeStorage", unsub = "unsubscribeStorage", item = Vec<Hash>)] | ||
fn subscribe_storage(&self, keys: Option<Vec<StorageKey>>); | ||
} | ||
|
||
pub struct RpcServerImpl; | ||
|
||
#[async_trait] | ||
impl RpcServer for RpcServerImpl { | ||
async fn storage_pairs(&self, _prefix: usize, _hash: Option<u128>) -> Result<Vec<usize>, Error> { | ||
Ok(vec![1, 2, 3, 4]) | ||
impl RpcServer<ExampleHash, ExampleStorageKey> for RpcServerImpl { | ||
async fn storage_keys( | ||
&self, | ||
storage_key: ExampleStorageKey, | ||
_hash: Option<ExampleHash>, | ||
) -> Result<Vec<ExampleStorageKey>, Error> { | ||
Ok(vec![storage_key]) | ||
} | ||
|
||
fn subscribe_storage(&self, mut sink: SubscriptionSink, keys: Option<Vec<u8>>) { | ||
sink.send(&keys.unwrap_or_default()).unwrap(); | ||
fn subscribe_storage(&self, mut sink: SubscriptionSink, _keys: Option<Vec<ExampleStorageKey>>) { | ||
sink.send(&vec![[0; 32]]).unwrap(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. technically, we don't have any compile time check that actually only |
||
} | ||
} | ||
|
||
|
@@ -64,18 +71,17 @@ async fn main() -> anyhow::Result<()> { | |
let url = format!("ws://{}", server_addr); | ||
|
||
let client = WsClientBuilder::default().build(&url).await?; | ||
assert_eq!(client.storage_pairs(10, None).await.unwrap(), vec![1, 2, 3, 4]); | ||
assert_eq!(client.storage_keys(vec![1, 2, 3, 4], None::<ExampleHash>).await.unwrap(), vec![vec![1, 2, 3, 4]]); | ||
|
||
let mut sub = client.subscribe_storage(None).await.unwrap(); | ||
assert_eq!(Some(vec![]), sub.next().await.unwrap()); | ||
let mut sub: Subscription<Vec<ExampleHash>> = | ||
RpcClient::<ExampleHash, ExampleStorageKey>::subscribe_storage(&client, None).await.unwrap(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. annoying to have to add these type hints but I think the issue for that is that we implement the client trait for T and these are not known in this cause at least not |
||
assert_eq!(Some(vec![[0; 32]]), sub.next().await.unwrap()); | ||
|
||
Ok(()) | ||
} | ||
|
||
async fn run_server() -> anyhow::Result<SocketAddr> { | ||
let server = WsServerBuilder::default().build("127.0.0.1:0").await?; | ||
let mut module = RpcModule::new(()); | ||
module.register_method("state_getPairs", |_, _| Ok(vec![1, 2, 3]))?; | ||
|
||
let addr = server.local_addr()?; | ||
tokio::spawn(async move { server.start(RpcServerImpl.into_rpc()).await }); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe produce a few more items here?