#![deny(missing_docs)]
extern crate jsonrpc_core as rpc;
#[derive(Default, Debug)]
pub struct Options {
pub no_print: bool,
}
#[derive(Default, Debug)]
pub struct Rpc {
pub io: rpc::IoHandler,
pub options: Options,
}
pub enum Encoding {
Compact,
Pretty,
}
impl From<rpc::IoHandler> for Rpc {
fn from(io: rpc::IoHandler) -> Self {
Rpc {
io,
..Default::default()
}
}
}
impl Rpc {
pub fn new<D>(delegate: D) -> Self
where
D: IntoIterator<Item = (String, rpc::RemoteProcedure<()>)>,
{
let mut io = rpc::IoHandler::new();
io.extend_with(delegate);
io.into()
}
pub fn request<T>(&self, method: &str, params: &T) -> String
where
T: serde::Serialize,
{
self.make_request(method, params, Encoding::Pretty)
}
pub fn make_request<T>(&self, method: &str, params: &T, encoding: Encoding) -> String
where
T: serde::Serialize,
{
use self::rpc::types::response;
let request = format!(
"{{ \"jsonrpc\":\"2.0\", \"id\": 1, \"method\": \"{}\", \"params\": {} }}",
method,
serde_json::to_string_pretty(params).expect("Serialization should be infallible."),
);
let response = self
.io
.handle_request_sync(&request)
.expect("We are sending a method call not notification.");
let extracted = match rpc::serde_from_str(&response).expect("We will always get a single output.") {
response::Output::Success(response::Success { result, .. }) => match encoding {
Encoding::Compact => serde_json::to_string(&result),
Encoding::Pretty => serde_json::to_string_pretty(&result),
},
response::Output::Failure(response::Failure { error, .. }) => match encoding {
Encoding::Compact => serde_json::to_string(&error),
Encoding::Pretty => serde_json::to_string_pretty(&error),
},
}
.expect("Serialization is infallible; qed");
println!("\n{}\n --> {}\n", request, extracted);
extracted
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn should_test_request_is_pretty() {
let rpc = {
let mut io = rpc::IoHandler::new();
io.add_sync_method("test_method", |_| Ok(rpc::Value::Array(vec![5.into(), 10.into()])));
Rpc::from(io)
};
assert_eq!(rpc.request("test_method", &[5u64]), "[\n 5,\n 10\n]");
}
#[test]
fn should_test_make_request_compact() {
let rpc = {
let mut io = rpc::IoHandler::new();
io.add_sync_method("test_method", |_| Ok(rpc::Value::Array(vec![5.into(), 10.into()])));
Rpc::from(io)
};
assert_eq!(rpc.make_request("test_method", &[5u64], Encoding::Compact), "[5,10]");
}
}