Crate embedded_jsonrpc

Source
Expand description

§JSON-RPC for Embedded Systems

This crate provides a JSON-RPC server implementation for embedded systems.

§Features

  • #![no_std] Support: Fully compatible with environments lacking a standard library.
  • Predictable Memory Usage: Zero dynamic allocation with statically sized buffers.
  • Async: Non-blocking I/O with embedded-io-async.
  • Client Compatibility: Uses LSP style framing for JSON-RPC messages.
  • Error Handling: Adheres to JSON-RPC standards with robust error reporting.

§Example Usage

use embedded_jsonrpc::{RpcError, RpcResponse, RpcServer, RpcHandler, JSONRPC_VERSION, DEFAULT_HANDLER_STACK_SIZE};
use embedded_jsonrpc::stackfuture::StackFuture;
use embedded_io_async::{Read, Write, ErrorType};

struct MyStream;

impl ErrorType for MyStream {
  type Error = embedded_io_async::ErrorKind;
}

impl Read for MyStream {
  async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
    Ok(0)
  }
}

impl Write for MyStream {
 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
  Ok(0)
 }
}

struct MyHandler;

impl RpcHandler for MyHandler {
   fn handle<'a>(&self, id: Option<u64>, _method: &'a str, _request_json: &'a [u8], response_json: &'a mut [u8]) -> StackFuture<'a, Result<usize, RpcError>, DEFAULT_HANDLER_STACK_SIZE> {
      StackFuture::from(async move {
         let response: RpcResponse<'static, ()> = RpcResponse {
           jsonrpc: JSONRPC_VERSION,
           error: None,
           result: None,
           id,
         };
        Ok(serde_json_core::to_slice(&response, response_json).unwrap())
     })
  }
}

async fn serve_requests() {
  let mut server: RpcServer<'_, _> = RpcServer::new();
  server.register_handler("echo", &MyHandler);

  loop {
    let mut stream: MyStream = MyStream;
    server.serve(&mut stream).await.unwrap();
  }
}

§License

This crate is licensed under the Mozilla Public License 2.0 (MPL-2.0). See the LICENSE file for more details.

§References

Modules§

stackfuture
This crate defines a StackFuture wrapper around futures that stores the wrapped future in space provided by the caller. This can be used to emulate dyn async traits without requiring heap allocation.

Structs§

RpcError
JSON-RPC Error structure
RpcRequest
JSON-RPC Request structure
RpcResponse
JSON-RPC Response structure
RpcServer
RPC server

Enums§

RpcErrorCode
JSON-RPC Standard Error Codes
RpcServerError
Type for errors returned by the RPC server

Constants§

DEFAULT_HANDLER_STACK_SIZE
Default stack size for futures. This is a rough estimate and will need to be adjusted based on the complexity of your handlers.
DEFAULT_HANDLER_TIMEOUT_MS
Default handler timeout in milliseconds. This is the maximum time allowed for a handler to process a request.
DEFAULT_MAX_CLIENTS
Default maximum number of clients.
DEFAULT_MAX_HANDLERS
Maximum number of registered RPC methods.
DEFAULT_MAX_MESSAGE_LEN
Maximum length of a JSON-RPC message (including headers). Default to the largest message that’ll fit in a single Ethernet frame.
DEFAULT_NOTIFICATION_QUEUE_SIZE
Default notification queue size. This is the maximum number of notifications that can be queued for sending.
DEFAULT_WRITE_TIMEOUT_MS
Default write timeout in milliseconds. This is the maximum time allowed for writing to the stream.
JSONRPC_VERSION
JSON-RPC Version Currently only supports version 2.0 https://www.jsonrpc.org/specification

Traits§

RpcHandler
Trait for RPC handlers TODO: when async closures are stabilized, we should offer a way to register closures directly.