use essrpc::essrpc; use essrpc::transports::{BincodeAsyncClientTransport, BincodeTransport, ReadWrite}; use essrpc::{AsyncRPCClient, RPCErrorKind, RPCServer}; use serde::{Deserialize, Serialize}; use std::env; use std::process::Stdio; use std::result::Result; use std::{fmt, thread}; use tokio; use tokio::process::Command; use tokio_util::compat::TokioAsyncReadCompatExt; #[tokio::main] pub async fn main() { use readwrite::ReadWriteAsyncstd; use tokio_util::compat::{Compat, TokioAsyncReadCompatExt, TokioAsyncWriteCompatExt}; let args: Vec = env::args().collect(); if args.len() > 1 { server().await; return; } // launch server let cmd = &args[0]; let mut server = Command::new(cmd) .arg("s") .stdin(Stdio::piped()) .stdout(Stdio::piped()) .stderr(Stdio::inherit()) .spawn() .expect("Failed to spawn remote server"); let server_in = server.stdin.as_mut().expect("Failed to open stdin"); let server_out = server.stdout.as_mut().expect("Failed to read stdout"); let server_io = ReadWriteAsyncstd::new(server_out.compat(), server_in.compat_write()); let remote = FooAsyncRPCClient::new(BincodeAsyncClientTransport::new(server_io)); println!( "{}", remote .bar("the answer".to_string(), 42) .await .expect("failed to run bar") ); println!("{:?}", remote.foo().await.expect("failed to run foo")); } async fn server() { use std::io::{self}; let stdin = io::stdin(); let stdout = io::stdout(); let stdio = ReadWrite::new(stdin, stdout); let mut serve = FooRPCServer::new(FooImpl::new(), BincodeTransport::new(stdio)); match serve.serve() { Ok(_) => panic!("Expected EOF error"), Err(e) => assert_eq!(e.kind, RPCErrorKind::TransportEOF), }; } #[derive(Debug, Deserialize, Serialize)] pub struct TestError { msg: String, } impl fmt::Display for TestError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "error: {}", self.msg) } } impl std::error::Error for TestError {} impl From for TestError { fn from(error: essrpc::RPCError) -> Self { TestError { msg: format!("{}", error), } } } #[essrpc(async, sync)] pub trait Foo { fn foo(&self) -> Result, TestError>; fn bar(&self, a: String, b: i32) -> Result; fn expect_error(&self) -> Result; } struct FooImpl; impl FooImpl { fn new() -> Self { FooImpl {} } } impl Foo for FooImpl { fn foo(&self) -> Result, TestError> { let mut a: Vec = Vec::new(); a.resize(1024, 0); Ok(a) } fn bar(&self, a: String, b: i32) -> Result { Ok(format!("{} is {}", a, b)) } fn expect_error(&self) -> Result { Err(TestError { msg: "iamerror".to_string(), }) } }