use essrpc::essrpc;
use essrpc::transports::{BincodeAsyncClientTransport, BincodeTransport, ReadWrite};
use essrpc::{AsyncRPCClient, RPCErrorKind, RPCServer};
use serde::{Deserialize, Serialize};
use std::env;
use std::fmt;
use std::process::Stdio;
use std::result::Result;
use tokio;
use tokio::process::Command;
#[tokio::main]
pub async fn main() {
use readwrite::ReadWriteTokio;
let args: Vec<String> = env::args().collect();
if args.len() > 1 {
server().await;
return;
}
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 = ReadWriteTokio::new(server_out, server_in);
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<essrpc::RPCError> for TestError {
fn from(error: essrpc::RPCError) -> Self {
TestError {
msg: format!("{}", error),
}
}
}
#[essrpc(async, sync)]
pub trait Foo {
fn foo(&self) -> Result<Vec<u8>, TestError>;
fn bar(&self, a: String, b: i32) -> Result<String, TestError>;
fn expect_error(&self) -> Result<String, TestError>;
}
struct FooImpl;
impl FooImpl {
fn new() -> Self {
FooImpl {}
}
}
impl Foo for FooImpl {
fn foo(&self) -> Result<Vec<u8>, TestError> {
let mut a: Vec<u8> = Vec::new();
a.resize(1024, 0);
Ok(a)
}
fn bar(&self, a: String, b: i32) -> Result<String, TestError> {
Ok(format!("{} is {}", a, b))
}
fn expect_error(&self) -> Result<String, TestError> {
Err(TestError {
msg: "iamerror".to_string(),
})
}
}