kkrpc 0.6.1

Rust client/server library for kkrpc JSON-mode interop
Documentation
# kkrpc-interop (Rust)

Rust client/server library for kkrpc JSON-mode interop. This crate implements the
kkrpc message protocol using JSON only for easy cross-language RPC.

## Features

- JSON-mode request/response compatible with kkrpc `serialization.version = "json"`.
- `stdio` and `ws` transports behind a `Transport` trait.
- Callback support using `__callback__<id>` tokens.

## Installation

When published:

```bash
cargo add kkrpc-interop
```

From this repository:

```bash
cd interop/rust

cargo test
```

## Usage

### Stdio client

```rust
use kkrpc::{Arg, Client, StdioTransport};
use serde_json::json;
use std::process::{Command, Stdio};
use std::sync::Arc;

fn main() {
    let mut child = Command::new("bun")
        .arg("interop/node/server.ts")
        .stdin(Stdio::piped())
        .stdout(Stdio::piped())
        .spawn()
        .expect("spawn bun server");

    let stdout = child.stdout.take().expect("stdout");
    let stdin = child.stdin.take().expect("stdin");

    let transport = StdioTransport::new(stdout, stdin);
    let client = Client::new(Arc::new(transport));

    let result = client
        .call("math.add", vec![Arg::Value(json!(1)), Arg::Value(json!(2))])
        .expect("call math.add");
    println!("{result}");
}
```

### WebSocket client

```rust
use kkrpc::{Arg, Client, WebSocketTransport};
use serde_json::json;

fn main() {
    let transport = WebSocketTransport::connect("ws://localhost:8789")
        .expect("connect ws");
    let client = Client::new(transport);

    let result = client
        .call("echo", vec![Arg::Value(json!({"hello": "kkrpc"}))])
        .expect("call echo");
    println!("{result}");
}
```

### Server

```rust
use kkrpc::{Arg, RpcApi, Server, StdioTransport};
use serde_json::Value;
use std::sync::Arc;

fn main() {
    let transport = Arc::new(StdioTransport::new(std::io::stdin(), std::io::stdout()));
    let mut api = RpcApi::new();
    api.register_method("math.add", Arc::new(|args: Vec<Arg>| {
        let a = match &args[0] { Arg::Value(value) => value.as_i64().unwrap_or(0), _ => 0 };
        let b = match &args[1] { Arg::Value(value) => value.as_i64().unwrap_or(0), _ => 0 };
        Value::from(a + b)
    }));

    let _server = Server::new(transport, api);
    loop {
        std::thread::park();
    }
}
```

## Tests

```bash
cd interop/rust

cargo test
```

## How it works with kkrpc

- **Message format**: JSON objects with `id`, `method`, `args`, `type`, `version`.
- **Line-delimited transport**: each JSON message ends with `\n`.
- **Callbacks**: function arguments are encoded as `__callback__<id>` and dispatched via
  `type = "callback"`.
- **Adapters**: `Transport` is the common trait for `StdioTransport` and
  `WebSocketTransport`.

Use `serialization.version = "json"` on the kkrpc JS side for compatibility.