11 个版本 (4 个重大变更)
0.5.3 | 2019年10月9日 |
---|---|
0.5.2 | 2019年4月23日 |
0.4.1 | 2019年3月7日 |
0.3.0 | 2019年3月7日 |
0.1.3 | 2019年2月22日 |
#21 in #rpc-server
45KB
910 行
Easy JSON RPC
根据特质定义生成 rpc 处理器和客户端辅助工具。 文档
定义 API
use easy_jsonrpc;
#[easy_jsonrpc::rpc]
pub trait Adder {
fn checked_add(&self, a: isize, b: isize) -> Option<isize>;
fn wrapping_add(&self, a: isize, b: isize) -> isize;
fn is_some(&self, a: Option<usize>) -> bool {
a.is_some()
}
fn takes_ref(&self, rf: &isize);
}
rpc 宏生成
- &dyn Adder 的 Handler 特质实现
- rpc 客户端的辅助模块
服务器端使用
use easy_jsonrpc::{Handler, MaybeReply};
use serde_json::json;
struct AdderImpl;
impl Adder for AdderImpl {
fn checked_add(&self, a: isize, b: isize) -> Option<isize> { a.checked_add(b) }
fn wrapping_add(&self, a: isize, b: isize) -> isize { a.wrapping_add(b) }
fn takes_ref(&self, rf: &isize) {}
}
let handler = (&AdderImpl {} as &dyn Adder);
assert_eq!(
handler.handle_request(json!({
"jsonrpc": "2.0",
"method": "wrapping_add",
"params": [1, 2],
"id": 1
})),
MaybeReply::Reply(json!({
"jsonrpc": "2.0",
"result": 3,
"id": 1
}))
);
客户端使用
let bind = adder::checked_add(1, 2).unwrap();
let (call, tracker) = bind.call();
let json_response = match handler.handle_request(call.as_request()) {
MaybeReply::Reply(resp) => resp,
MaybeReply::DontReply => panic!(),
};
let mut response = easy_jsonrpc::Response::from_json_response(json_response).unwrap();
assert_eq!(tracker.get_return(&mut response).unwrap(), Some(3));
额外功能
命名参数可以免费处理。
assert_eq!(
handler.handle_request(json!({
"jsonrpc": "2.0",
"method": "wrapping_add",
"params": {
"a": 1,
"b": 2
},
"id": 1
})),
MaybeReply::Reply(json!({
"jsonrpc": "2.0",
"result": 3,
"id": 1
}))
);
通知(不带 id 的调用)被合理处理。
assert_eq!(
handler.handle_request(json!({
"jsonrpc": "2.0",
"method": "wrapping_add",
"params": [1, 1]
})),
MaybeReply::DontReply
);
生成通知很容易。
let bind = adder::checked_add(0, 0).unwrap();
let notification = bind.notification().as_request();
assert_eq!(handler.handle_request(notification), MaybeReply::DontReply);
支持批量调用。
use easy_jsonrpc::Call;
let bind0 = adder::checked_add(0, 0).unwrap();
let (call0, tracker0) = bind0.call();
let bind1 = adder::checked_add(1, 0).unwrap();
let (call1, tracker1) = bind1.call();
let bind2 = adder::wrapping_add(1, 1).unwrap();
let (call2, tracker2) = bind2.call();
let bind3 = adder::wrapping_add(1, 1).unwrap();
let call3 = bind3.notification();
let json_request = Call::batch_request(&[call0, call1, call2, call3]);
let json_response = match handler.handle_request(json_request) {
MaybeReply::Reply(resp) => resp,
MaybeReply::DontReply => panic!(),
};
let mut response = easy_jsonrpc::Response::from_json_response(json_response).unwrap();
assert_eq!(tracker1.get_return(&mut response).unwrap(), Some(1));
assert_eq!(tracker0.get_return(&mut response).unwrap(), Some(0));
assert_eq!(tracker2.get_return(&mut response).unwrap(), 2);
依赖项
~4MB
~83K SLoC