//! JSON-RPC 2.0 request/response types and helpers. use poem::http::StatusCode; use poem::{Body, Response}; use serde::{Deserialize, Serialize}; use serde_json::Value; // ── JSON-RPC types ────────────────────────────────────────────────────────── /// JSON-RPC request. #[derive(Deserialize)] pub(super) struct JsonRpcRequest { pub(super) jsonrpc: String, pub(super) id: Option, pub(super) method: String, #[serde(default)] pub(super) params: Value, } /// JSON-RPC response. #[derive(Serialize)] pub(crate) struct JsonRpcResponse { jsonrpc: &'static str, #[serde(skip_serializing_if = "Option::is_none")] pub(crate) id: Option, #[serde(skip_serializing_if = "Option::is_none")] pub(crate) result: Option, #[serde(skip_serializing_if = "Option::is_none")] pub(crate) error: Option, } #[derive(Debug, Serialize)] pub(crate) struct JsonRpcError { code: i64, pub(crate) message: String, } impl JsonRpcResponse { pub(crate) fn success(id: Option, result: Value) -> Self { Self { jsonrpc: "2.0", id, result: Some(result), error: None, } } pub(crate) fn error(id: Option, code: i64, message: String) -> Self { Self { jsonrpc: "2.0", id, result: None, error: Some(JsonRpcError { code, message }), } } } pub(super) fn to_json_response(resp: JsonRpcResponse) -> Response { let body = serde_json::to_vec(&resp).unwrap_or_default(); Response::builder() .status(StatusCode::OK) .header("Content-Type", "application/json") .body(Body::from(body)) }