Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use jsonrpsee_types::error::Error;
use jsonrpsee_types::v2::{traits::RpcMethod, RpcError, RpcParams};
use jsonrpsee_utils::server_utils::{send_response, Methods};
use serde::Serialize;
use std::sync::Arc;
#[derive(Default)]
pub struct RpcModule {
methods: Methods,
}
impl RpcModule {
/// Instantiate a new `RpcModule`.
pub fn new() -> Self {
RpcModule { methods: Methods::default() }
}
/// Add context for this module, turning it into an `RpcContextModule`.
pub fn with_context<Context>(self, ctx: Context) -> RpcContextModule<Context> {
RpcContextModule { ctx: Arc::new(ctx), module: self }
}
fn verify_method_name(&mut self, name: &str) -> Result<(), Error> {
if self.methods.get(name).is_some() {
return Err(Error::MethodAlreadyRegistered(name.into()));
}
Ok(())
}
/// Register a new RPC method, which responds with a given callback.
pub fn register_method<F, R>(&mut self, method_name: &'static str, callback: F) -> Result<(), Error>
where
R: Serialize,
F: RpcMethod<R>,
{
self.verify_method_name(method_name)?;
self.methods.insert(
method_name,
Box::new(move |id, params, tx, _| {
let result = callback(params)?;
send_response(id, tx, result);
Ok(())
}),
);
Ok(())
}
pub(crate) fn into_methods(self) -> Methods {
self.methods
}
pub(crate) fn merge(&mut self, other: RpcModule) -> Result<(), Error> {
for name in other.methods.keys() {
self.verify_method_name(name)?;
}
for (name, callback) in other.methods {
self.methods.insert(name, callback);
}
Ok(())
}
}
pub struct RpcContextModule<Context> {
ctx: Arc<Context>,
module: RpcModule,
}
impl<Context> RpcContextModule<Context> {
/// Create a new module with a given shared `Context`.
pub fn new(ctx: Context) -> Self {
RpcContextModule { ctx: Arc::new(ctx), module: RpcModule::new() }
}
/// Register a new RPC method, which responds with a given callback.
pub fn register_method<F, R>(&mut self, method_name: &'static str, callback: F) -> Result<(), Error>
where
Context: Send + Sync + 'static,
R: Serialize,
F: Fn(RpcParams, &Context) -> Result<R, RpcError> + Send + Sync + 'static,
{
self.module.verify_method_name(method_name)?;
let ctx = self.ctx.clone();
self.module.methods.insert(
method_name,
Box::new(move |id, params, tx, _| {
let result = callback(params, &*ctx)?;
send_response(id, tx, result);
Ok(())
}),
);
Ok(())
}
/// Convert this `RpcContextModule` into a regular `RpcModule` that can be registered on the `Server`.
pub fn into_module(self) -> RpcModule {
self.module
}
}