Skip to content

Commit 51ad234

Browse files
committed
implement custom generator on IdKind
1 parent 9272591 commit 51ad234

File tree

4 files changed

+114
-3
lines changed

4 files changed

+114
-3
lines changed

core/src/client/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ cfg_async_client! {
3333

3434
pub mod error;
3535
pub use error::Error;
36+
use jsonrpsee_types::request::IdGeneratorFn;
3637

3738
use std::fmt;
3839
use std::ops::Range;
@@ -485,14 +486,17 @@ pub enum IdKind {
485486
String,
486487
/// Number.
487488
Number,
489+
/// Custom generator.
490+
Custom(IdGeneratorFn),
488491
}
489492

490493
impl IdKind {
491-
/// Generate an `Id` from number.
494+
/// Generate an `Id` from number or from a registered generator.
492495
pub fn into_id(self, id: u64) -> Id<'static> {
493496
match self {
494497
IdKind::Number => Id::Number(id),
495498
IdKind::String => Id::Str(format!("{id}").into()),
499+
IdKind::Custom(generator) => generator.call(),
496500
}
497501
}
498502
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright 2019-2021 Parity Technologies (UK) Ltd.
2+
//
3+
// Permission is hereby granted, free of charge, to any
4+
// person obtaining a copy of this software and associated
5+
// documentation files (the "Software"), to deal in the
6+
// Software without restriction, including without
7+
// limitation the rights to use, copy, modify, merge,
8+
// publish, distribute, sublicense, and/or sell copies of
9+
// the Software, and to permit persons to whom the Software
10+
// is furnished to do so, subject to the following
11+
// conditions:
12+
//
13+
// The above copyright notice and this permission notice
14+
// shall be included in all copies or substantial portions
15+
// of the Software.
16+
//
17+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
18+
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
19+
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
20+
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
21+
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22+
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23+
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
24+
// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25+
// DEALINGS IN THE SOFTWARE.
26+
27+
use std::net::SocketAddr;
28+
29+
use jsonrpsee::client_transport::ws::{Url, WsTransportClientBuilder};
30+
use jsonrpsee::core::client::{Client, ClientBuilder, ClientT, IdKind};
31+
use jsonrpsee::rpc_params;
32+
use jsonrpsee::server::{RpcModule, Server};
33+
use jsonrpsee::types::{Id, IdGeneratorFn};
34+
35+
#[tokio::main]
36+
async fn main() -> anyhow::Result<()> {
37+
tracing_subscriber::FmtSubscriber::builder()
38+
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
39+
.try_init()
40+
.expect("setting default subscriber failed");
41+
42+
let addr = run_server().await?;
43+
let uri = Url::parse(&format!("ws://{}", addr))?;
44+
45+
let custom_generator = IdGeneratorFn::new(generate_timestamp_id);
46+
47+
let (tx, rx) = WsTransportClientBuilder::default().build(uri).await?;
48+
let client: Client = ClientBuilder::default().id_format(IdKind::Custom(custom_generator)).build_with_tokio(tx, rx);
49+
50+
let response: String = client.request("say_hello", rpc_params![]).await?;
51+
tracing::info!("response: {:?}", response);
52+
53+
Ok(())
54+
}
55+
56+
async fn run_server() -> anyhow::Result<SocketAddr> {
57+
let server = Server::builder().build("127.0.0.1:0").await?;
58+
let mut module = RpcModule::new(());
59+
module.register_method("say_hello", |_, _, _| "lo")?;
60+
let addr = server.local_addr()?;
61+
62+
let handle = server.start(module);
63+
64+
// In this example we don't care about doing shutdown so let's it run forever.
65+
// You may use the `ServerHandle` to shut it down or manage it yourself.
66+
tokio::spawn(handle.stopped());
67+
68+
Ok(addr)
69+
}
70+
71+
fn generate_timestamp_id() -> Id<'static> {
72+
let timestamp =
73+
std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).expect("Time went backwards").as_secs();
74+
Id::Number(timestamp)
75+
}

types/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,5 @@ pub mod error;
4545

4646
pub use error::{ErrorCode, ErrorObject, ErrorObjectOwned};
4747
pub use params::{Id, InvalidRequestId, Params, ParamsSequence, SubscriptionId, TwoPointZero};
48-
pub use request::{InvalidRequest, Notification, NotificationSer, Request, RequestSer};
48+
pub use request::{IdGeneratorFn, InvalidRequest, Notification, NotificationSer, Request, RequestSer};
4949
pub use response::{Response, ResponsePayload, SubscriptionPayload, SubscriptionResponse, Success as ResponseSuccess};

types/src/request.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@
2727
//! Types to handle JSON-RPC requests according to the [spec](https://www.jsonrpc.org/specification#request-object).
2828
//! Some types come with a "*Ser" variant that implements [`serde::Serialize`]; these are used in the client.
2929
30-
use std::borrow::Cow;
30+
use std::{
31+
borrow::Cow,
32+
fmt::{Debug, Formatter, Result},
33+
};
3134

3235
use crate::{
3336
Params,
@@ -173,6 +176,35 @@ impl<'a> NotificationSer<'a> {
173176
}
174177
}
175178

179+
/// Custom id generator function
180+
pub struct IdGeneratorFn(fn() -> Id<'static>);
181+
182+
impl IdGeneratorFn {
183+
/// Creates a new `IdGeneratorFn` from a function pointer.
184+
pub fn new(generator: fn() -> Id<'static>) -> Self {
185+
IdGeneratorFn(generator)
186+
}
187+
188+
/// Calls the id generator function
189+
pub fn call(&self) -> Id<'static> {
190+
(self.0)()
191+
}
192+
}
193+
194+
impl Copy for IdGeneratorFn {}
195+
196+
impl Clone for IdGeneratorFn {
197+
fn clone(&self) -> Self {
198+
*self
199+
}
200+
}
201+
202+
impl Debug for IdGeneratorFn {
203+
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
204+
f.write_str("<CustomIdGenerator>")
205+
}
206+
}
207+
176208
#[cfg(test)]
177209
mod test {
178210
use super::{Cow, Id, InvalidRequest, Notification, NotificationSer, Request, RequestSer, TwoPointZero};

0 commit comments

Comments
 (0)