jsoncall 0.0.3

A simple asynchronous JSON-RPC 2.0 library leveraging Rust's type system
Documentation
use std::time::Duration;

use serde::{Deserialize, Serialize};
use tokio::{
    io::{AsyncBufRead, AsyncWrite, AsyncWriteExt, BufReader, duplex, split},
    time::sleep,
};

use jsoncall::{
    ErrorCode, Handler, Params, RequestContext, Response, Result, Session, SessionOptions,
};

fn make_channel_and_stream() -> (Session, impl AsyncBufRead, impl AsyncWrite) {
    let (d0, d1) = duplex(1024);
    let (r0, w0) = split(d0);
    let (r1, w1) = split(d1);
    (
        Session::new(
            HelloService,
            BufReader::new(r0),
            w0,
            &SessionOptions::default(),
        ),
        BufReader::new(r1),
        w1,
    )
}

#[tokio::main]
async fn main() -> Result<()> {
    let (server, r, mut w) = make_channel_and_stream();
    w.write_all(b"aaa\n").await?;
    w.flush().await?;
    let client = Session::new(HelloService, r, w, &SessionOptions::default());
    let rs = server.wait().await;
    assert!(rs.is_err());
    let rc = client.wait().await;
    assert!(rc.is_err());
    assert_eq!(
        rc.unwrap_err().error_object().unwrap().code,
        ErrorCode::PARSE_ERROR
    );

    Ok(())
}
#[derive(Debug, Serialize, Deserialize)]
struct HelloRequest {
    name: String,
}

#[derive(Debug, Serialize, Deserialize)]
struct HelloResponse {
    message: String,
}

struct HelloService;
impl Handler for HelloService {
    fn request(&mut self, method: &str, params: Params, cx: RequestContext) -> Result<Response> {
        fn hello(r: HelloRequest) -> Result<HelloResponse> {
            Ok(HelloResponse {
                message: format!("Hello, {}!", r.name),
            })
        }
        async fn hello_async(r: HelloRequest) -> Result<HelloResponse> {
            sleep(Duration::from_millis(100)).await;
            Ok(HelloResponse {
                message: format!("HelloAsync, {}!", r.name),
            })
        }
        match method {
            "hello" => cx.handle(hello(params.to()?)),
            "hello_async" => cx.handle_async(hello_async(params.to()?)),
            _ => cx.method_not_found(),
        }
    }
}