tetsy_jsonrpc_stdio_server/
lib.rs1#![deny(missing_docs)]
19
20use tokio;
21use tokio_stdin_stdout;
22#[macro_use]
23extern crate log;
24
25pub use tetsy_jsonrpc_core;
26
27use tetsy_jsonrpc_core::IoHandler;
28use std::sync::Arc;
29use tokio::prelude::{Future, Stream};
30use tokio_codec::{FramedRead, FramedWrite, LinesCodec};
31
32pub struct ServerBuilder {
34 handler: Arc<IoHandler>,
35}
36
37impl ServerBuilder {
38 pub fn new<T>(handler: T) -> Self
40 where
41 T: Into<IoHandler>,
42 {
43 ServerBuilder {
44 handler: Arc::new(handler.into()),
45 }
46 }
47
48 pub fn build(&self) {
52 let stdin = tokio_stdin_stdout::stdin(0);
53 let stdout = tokio_stdin_stdout::stdout(0).make_sendable();
54
55 let framed_stdin = FramedRead::new(stdin, LinesCodec::new());
56 let framed_stdout = FramedWrite::new(stdout, LinesCodec::new());
57
58 let handler = self.handler.clone();
59 let future = framed_stdin
60 .and_then(move |line| process(&handler, line).map_err(|_| unreachable!()))
61 .forward(framed_stdout)
62 .map(|_| ())
63 .map_err(|e| panic!("{:?}", e));
64
65 tokio::run(future);
66 }
67}
68
69fn process(io: &Arc<IoHandler>, input: String) -> impl Future<Item = String, Error = ()> + Send {
71 io.handle_request(&input).map(move |result| match result {
72 Some(res) => res,
73 None => {
74 info!("JSON RPC request produced no response: {:?}", input);
75 String::from("")
76 }
77 })
78}