#![warn(missing_docs)]
extern crate susy_jsonrpc_core as rpc;
use serde;
use serde_json;
use std::collections::HashMap;
#[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: Into<HashMap<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 serde_json::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_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_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]"
);
}
}