Skip to main content

tidepool_server/
json_rpc.rs

1//! JSON-RPC 2.0 envelope types. Kept minimal + lenient — Solana's
2//! RPC ecosystem varies slightly between 1.0 / 2.0 implementations
3//! and we want to pass through whatever clients send without over-
4//! validating.
5
6use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Deserialize)]
9pub struct JsonRpcRequest {
10    /// Always "2.0" in practice — we don't check.
11    #[serde(default)]
12    pub jsonrpc: Option<String>,
13    pub method: String,
14    #[serde(default)]
15    pub params: serde_json::Value,
16    #[serde(default)]
17    pub id: serde_json::Value,
18}
19
20#[derive(Debug, Serialize)]
21pub struct JsonRpcSuccess<'a> {
22    pub jsonrpc: &'static str,
23    pub id: &'a serde_json::Value,
24    pub result: serde_json::Value,
25}
26
27#[derive(Debug, Serialize)]
28pub struct JsonRpcFailure<'a> {
29    pub jsonrpc: &'static str,
30    pub id: &'a serde_json::Value,
31    pub error: JsonRpcError,
32}
33
34#[derive(Debug, Serialize)]
35pub struct JsonRpcError {
36    pub code: i32,
37    pub message: String,
38    #[serde(skip_serializing_if = "Option::is_none")]
39    pub data: Option<serde_json::Value>,
40}
41
42#[must_use]
43pub fn ok(id: &serde_json::Value, result: serde_json::Value) -> serde_json::Value {
44    serde_json::to_value(JsonRpcSuccess {
45        jsonrpc: "2.0",
46        id,
47        result,
48    })
49    .expect("JsonRpcSuccess is always serializable")
50}
51
52#[must_use]
53pub fn fail(id: &serde_json::Value, code: i32, message: impl Into<String>) -> serde_json::Value {
54    serde_json::to_value(JsonRpcFailure {
55        jsonrpc: "2.0",
56        id,
57        error: JsonRpcError {
58            code,
59            message: message.into(),
60            data: None,
61        },
62    })
63    .expect("JsonRpcFailure is always serializable")
64}
65
66// Standard-ish error codes used throughout the server.
67pub mod codes {
68    pub const INVALID_PARAMS: i32 = -32602;
69    pub const INTERNAL_ERROR: i32 = -32000;
70    pub const METHOD_NOT_FOUND: i32 = -32601;
71}