Skip to content

Commit

Permalink
remove ParamsSer::NoParams (#501)
Browse files Browse the repository at this point in the history
* fix(ParamsSer): serialize to empty array

Serialize `ParamsSer::NoParams` to an empty array inorder to comply with the jsonrpc v2 spec.

* fix tests

* remove ParamsSer::NoParams

* address grumbles: adjust rpc params macro
  • Loading branch information
niklasad1 authored Oct 11, 2021
1 parent 36bdb85 commit b3e4297
Show file tree
Hide file tree
Showing 17 changed files with 97 additions and 137 deletions.
31 changes: 10 additions & 21 deletions benches/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,15 @@ pub fn jsonrpsee_types_v2(crit: &mut Criterion) {
b.iter(|| {
let params = &[1_u64.into(), 2_u32.into()];
let params = ParamsSer::ArrayRef(params);
let request = RequestSer::new(Id::Number(0), "say_hello", params);
let request = RequestSer::new(Id::Number(0), "say_hello", Some(params));
v2_serialize(request);
})
});

crit.bench_function("jsonrpsee_types_v2_vec", |b| {
b.iter(|| {
let params = ParamsSer::Array(vec![1_u64.into(), 2_u32.into()]);
let request = RequestSer::new(Id::Number(0), "say_hello", params);
let request = RequestSer::new(Id::Number(0), "say_hello", Some(params));
v2_serialize(request);
})
});
Expand Down Expand Up @@ -137,7 +137,7 @@ impl RequestBencher for AsyncBencher {
fn run_round_trip(rt: &TokioRuntime, crit: &mut Criterion, client: Arc<impl Client>, name: &str, request: RequestType) {
crit.bench_function(&request.group_name(name), |b| {
b.to_async(rt).iter(|| async {
black_box(client.request::<String>(request.method_name(), ParamsSer::NoParams).await.unwrap());
black_box(client.request::<String>(request.method_name(), None).await.unwrap());
})
});
}
Expand All @@ -146,9 +146,7 @@ fn run_sub_round_trip(rt: &TokioRuntime, crit: &mut Criterion, client: Arc<impl
let mut group = crit.benchmark_group(name);
group.bench_function("subscribe", |b| {
b.to_async(rt).iter_with_large_drop(|| async {
black_box(
client.subscribe::<String>(SUB_METHOD_NAME, ParamsSer::NoParams, UNSUB_METHOD_NAME).await.unwrap(),
);
black_box(client.subscribe::<String>(SUB_METHOD_NAME, None, UNSUB_METHOD_NAME).await.unwrap());
})
});
group.bench_function("subscribe_response", |b| {
Expand All @@ -158,10 +156,7 @@ fn run_sub_round_trip(rt: &TokioRuntime, crit: &mut Criterion, client: Arc<impl
// runtime context and simply calling `block_on` here will cause the code to panic.
tokio::task::block_in_place(|| {
tokio::runtime::Handle::current().block_on(async {
client
.subscribe::<String>(SUB_METHOD_NAME, ParamsSer::NoParams, UNSUB_METHOD_NAME)
.await
.unwrap()
client.subscribe::<String>(SUB_METHOD_NAME, None, UNSUB_METHOD_NAME).await.unwrap()
})
})
},
Expand All @@ -178,7 +173,7 @@ fn run_sub_round_trip(rt: &TokioRuntime, crit: &mut Criterion, client: Arc<impl
b.iter_with_setup(
|| {
rt.block_on(async {
client.subscribe::<String>(SUB_METHOD_NAME, ParamsSer::NoParams, UNSUB_METHOD_NAME).await.unwrap()
client.subscribe::<String>(SUB_METHOD_NAME, None, UNSUB_METHOD_NAME).await.unwrap()
})
},
|sub| {
Expand All @@ -201,7 +196,7 @@ fn run_round_trip_with_batch(
) {
let mut group = crit.benchmark_group(request.group_name(name));
for batch_size in [2, 5, 10, 50, 100usize].iter() {
let batch = vec![(request.method_name(), ParamsSer::NoParams); *batch_size];
let batch = vec![(request.method_name(), None); *batch_size];
group.throughput(Throughput::Elements(*batch_size as u64));
group.bench_with_input(BenchmarkId::from_parameter(batch_size), batch_size, |b, _| {
b.to_async(rt).iter(|| async { client.batch_request::<String>(batch.clone()).await.unwrap() })
Expand All @@ -225,9 +220,7 @@ fn run_concurrent_round_trip<C: 'static + Client + Send + Sync>(
|clients| async {
let tasks = clients.map(|client| {
rt.spawn(async move {
let _ = black_box(
client.request::<String>(request.method_name(), ParamsSer::NoParams).await.unwrap(),
);
let _ = black_box(client.request::<String>(request.method_name(), None).await.unwrap());
})
});
join_all(tasks).await;
Expand Down Expand Up @@ -260,9 +253,7 @@ fn run_ws_concurrent_connections(rt: &TokioRuntime, crit: &mut Criterion, url: &
|clients| async {
let tasks = clients.into_iter().map(|client| {
rt.spawn(async move {
let _ = black_box(
client.request::<String>(request.method_name(), ParamsSer::NoParams).await.unwrap(),
);
let _ = black_box(client.request::<String>(request.method_name(), None).await.unwrap());
})
});
join_all(tasks).await;
Expand All @@ -288,9 +279,7 @@ fn run_http_concurrent_connections(
|clients| async {
let tasks = clients.map(|client| {
rt.spawn(async move {
let _ = black_box(
client.request::<String>(request.method_name(), ParamsSer::NoParams).await.unwrap(),
);
let _ = black_box(client.request::<String>(request.method_name(), None).await.unwrap());
})
});
join_all(tasks).await;
Expand Down
4 changes: 2 additions & 2 deletions examples/ws.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
// DEALINGS IN THE SOFTWARE.

use jsonrpsee::{
types::{traits::Client, v2::ParamsSer},
types::traits::Client,
ws_client::WsClientBuilder,
ws_server::{RpcModule, WsServerBuilder},
};
Expand All @@ -38,7 +38,7 @@ async fn main() -> anyhow::Result<()> {
let url = format!("ws://{}", addr);

let client = WsClientBuilder::default().build(&url).await?;
let response: String = client.request("say_hello", ParamsSer::NoParams).await?;
let response: String = client.request("say_hello", None).await?;
println!("r: {:?}", response);

Ok(())
Expand Down
8 changes: 4 additions & 4 deletions examples/ws_sub_with_params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

use jsonrpsee::{
rpc_params,
types::{traits::SubscriptionClient, v2::ParamsSer},
types::traits::SubscriptionClient,
ws_client::WsClientBuilder,
ws_server::{RpcModule, WsServerBuilder},
};
Expand All @@ -42,12 +42,12 @@ async fn main() -> anyhow::Result<()> {

// Subscription with a single parameter
let mut sub_params_one =
client.subscribe::<Option<char>>("sub_one_param", rpc_params!(3), "unsub_one_param").await?;
client.subscribe::<Option<char>>("sub_one_param", rpc_params![3], "unsub_one_param").await?;
println!("subscription with one param: {:?}", sub_params_one.next().await);

// Subscription with multiple parameters
let params = ParamsSer::Array(vec![2.into(), 5.into()]);
let mut sub_params_two = client.subscribe::<String>("sub_params_two", params, "unsub_params_two").await?;
let mut sub_params_two =
client.subscribe::<String>("sub_params_two", rpc_params![2, 5], "unsub_params_two").await?;
println!("subscription with two params: {:?}", sub_params_two.next().await);

Ok(())
Expand Down
2 changes: 1 addition & 1 deletion examples/ws_subscription.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ async fn main() -> anyhow::Result<()> {

let client = WsClientBuilder::default().build(&url).await?;
let mut subscribe_hello: Subscription<String> =
client.subscribe("subscribe_hello", rpc_params!(), "unsubscribe_hello").await?;
client.subscribe("subscribe_hello", rpc_params![], "unsubscribe_hello").await?;

let mut i = 0;
while i <= NUM_SUBSCRIPTION_RESPONSES {
Expand Down
6 changes: 3 additions & 3 deletions http-client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ pub struct HttpClient {

#[async_trait]
impl Client for HttpClient {
async fn notification<'a>(&self, method: &'a str, params: ParamsSer<'a>) -> Result<(), Error> {
async fn notification<'a>(&self, method: &'a str, params: Option<ParamsSer<'a>>) -> Result<(), Error> {
let notif = NotificationSer::new(method, params);
let fut = self.transport.send(serde_json::to_string(&notif).map_err(Error::ParseError)?);
match tokio::time::timeout(self.request_timeout, fut).await {
Expand All @@ -108,7 +108,7 @@ impl Client for HttpClient {
}

/// Perform a request towards the server.
async fn request<'a, R>(&self, method: &'a str, params: ParamsSer<'a>) -> Result<R, Error>
async fn request<'a, R>(&self, method: &'a str, params: Option<ParamsSer<'a>>) -> Result<R, Error>
where
R: DeserializeOwned,
{
Expand Down Expand Up @@ -150,7 +150,7 @@ impl Client for HttpClient {
}
}

async fn batch_request<'a, R>(&self, batch: Vec<(&'a str, ParamsSer<'a>)>) -> Result<Vec<R>, Error>
async fn batch_request<'a, R>(&self, batch: Vec<(&'a str, Option<ParamsSer<'a>>)>) -> Result<Vec<R>, Error>
where
R: DeserializeOwned + Default + Clone,
{
Expand Down
21 changes: 8 additions & 13 deletions http-client/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ use crate::HttpClientBuilder;
use jsonrpsee_test_utils::helpers::*;
use jsonrpsee_test_utils::mocks::Id;
use jsonrpsee_test_utils::TimeoutFutureExt;
use jsonrpsee_utils::rpc_params;

#[tokio::test]
async fn method_call_works() {
Expand All @@ -50,7 +51,7 @@ async fn notification_works() {
let uri = format!("http://{}", server_addr);
let client = HttpClientBuilder::default().build(&uri).unwrap();
client
.notification("i_dont_care_about_the_response_because_the_server_should_not_respond", ParamsSer::NoParams)
.notification("i_dont_care_about_the_response_because_the_server_should_not_respond", None)
.with_default_timeout()
.await
.unwrap()
Expand Down Expand Up @@ -110,11 +111,8 @@ async fn subscription_response_to_request() {

#[tokio::test]
async fn batch_request_works() {
let batch_request = vec![
("say_hello", ParamsSer::NoParams),
("say_goodbye", ParamsSer::Array(vec![0_u64.into(), 1.into(), 2.into()])),
("get_swag", ParamsSer::NoParams),
];
let batch_request =
vec![("say_hello", rpc_params![]), ("say_goodbye", rpc_params![0_u64, 1, 2]), ("get_swag", None)];
let server_response = r#"[{"jsonrpc":"2.0","result":"hello","id":0}, {"jsonrpc":"2.0","result":"goodbye","id":1}, {"jsonrpc":"2.0","result":"here's your swag","id":2}]"#.to_string();
let response =
run_batch_request_with_response(batch_request, server_response).with_default_timeout().await.unwrap().unwrap();
Expand All @@ -123,19 +121,16 @@ async fn batch_request_works() {

#[tokio::test]
async fn batch_request_out_of_order_response() {
let batch_request = vec![
("say_hello", ParamsSer::NoParams),
("say_goodbye", ParamsSer::Array(vec![0_u64.into(), 1.into(), 2.into()])),
("get_swag", ParamsSer::NoParams),
];
let batch_request =
vec![("say_hello", rpc_params! {}), ("say_goodbye", rpc_params![0_u64, 1, 2]), ("get_swag", None)];
let server_response = r#"[{"jsonrpc":"2.0","result":"here's your swag","id":2}, {"jsonrpc":"2.0","result":"hello","id":0}, {"jsonrpc":"2.0","result":"goodbye","id":1}]"#.to_string();
let response =
run_batch_request_with_response(batch_request, server_response).with_default_timeout().await.unwrap().unwrap();
assert_eq!(response, vec!["hello".to_string(), "goodbye".to_string(), "here's your swag".to_string()]);
}

async fn run_batch_request_with_response<'a>(
batch: Vec<(&'a str, ParamsSer<'a>)>,
batch: Vec<(&'a str, Option<ParamsSer<'a>>)>,
response: String,
) -> Result<Vec<String>, Error> {
let server_addr = http_server_with_hardcoded_response(response).with_default_timeout().await.unwrap();
Expand All @@ -148,7 +143,7 @@ async fn run_request_with_response(response: String) -> Result<JsonValue, Error>
let server_addr = http_server_with_hardcoded_response(response).with_default_timeout().await.unwrap();
let uri = format!("http://{}", server_addr);
let client = HttpClientBuilder::default().build(&uri).unwrap();
client.request("say_hello", ParamsSer::NoParams).with_default_timeout().await.unwrap()
client.request("say_hello", None).with_default_timeout().await.unwrap()
}

fn assert_jsonrpc_error_response(err: Error, exp: ErrorObject) {
Expand Down
8 changes: 4 additions & 4 deletions proc-macros/src/render_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,10 @@ impl RpcDescription {
quote! { #serde_json::to_value(&#param)? }
});
quote! {
vec![ #(#params),* ].into()
Some(vec![ #(#params),* ].into())
}
} else {
self.jrps_client_item(quote! { types::v2::params::ParamsSer::NoParams })
quote! { None }
};

// Doc-comment to be associated with the method.
Expand Down Expand Up @@ -144,10 +144,10 @@ impl RpcDescription {
quote! { #serde_json::to_value(&#param)? }
});
quote! {
vec![ #(#params),* ].into()
Some(vec![ #(#params),* ].into())
}
} else {
self.jrps_client_item(quote! { types::v2::params::ParamsSer::NoParams })
quote! { None }
};

// Doc-comment to be associated with the method.
Expand Down
22 changes: 7 additions & 15 deletions proc-macros/tests/ui/correct/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
use jsonrpsee::{
proc_macros::rpc,
types::{async_trait, to_json_value, traits::Client, v2::params::ParamsSer, RpcResult},
rpc_params,
types::{async_trait, traits::Client, RpcResult},
ws_client::*,
ws_server::{SubscriptionSink, WsServerBuilder},
};
Expand Down Expand Up @@ -90,20 +91,11 @@ async fn main() {
assert_eq!(client.optional_params(Some(1), "a".into()).await.unwrap(), true);

assert_eq!(client.array_params(vec![1]).await.unwrap(), 1);
assert_eq!(
client
.request::<u64>("foo_array_params", vec![to_json_value(Vec::<u64>::new()).unwrap()].into())
.await
.unwrap(),
0
);

assert_eq!(client.request::<bool>("foo_optional_param", vec![].into()).await.unwrap(), false);
assert_eq!(client.request::<bool>("foo_optional_param", ParamsSer::NoParams).await.unwrap(), false);
assert_eq!(
client.request::<bool>("foo_optional_param", vec![to_json_value(Some(1)).unwrap()].into()).await.unwrap(),
true
);
assert_eq!(client.request::<u64>("foo_array_params", rpc_params![Vec::<u64>::new()]).await.unwrap(), 0);

assert_eq!(client.request::<bool>("foo_optional_param", rpc_params![]).await.unwrap(), false);
assert_eq!(client.request::<bool>("foo_optional_param", None).await.unwrap(), false);
assert_eq!(client.request::<bool>("foo_optional_param", rpc_params![1]).await.unwrap(), true);

let mut sub = client.sub().await.unwrap();
let first_recv = sub.next().await.unwrap();
Expand Down
Loading

0 comments on commit b3e4297

Please sign in to comment.