rustic_jsonrpc/
lib.rs

1#![doc = include_str!("../README.md")]
2
3use std::error::Error as StdError;
4use std::fmt::{Display, Formatter};
5
6pub use serde;
7use serde::de::{Error as SerdeError, Unexpected};
8use serde::{Deserialize, Deserializer, Serialize, Serializer};
9pub use serde_json;
10use serde_json::value::RawValue;
11use serde_json::Value;
12
13pub use container::Container;
14pub use registry::*;
15
16/// Method attribute macro.
17pub use rustic_jsonrpc_macro::method;
18
19/// Method identifier generation macro.
20pub use rustic_jsonrpc_macro::method_ident;
21
22/// Macro to generate an array of method identifiers.
23#[macro_export]
24macro_rules! methods {
25    ($($name:ident),+ $(,)?) => {
26        &[$(rustic_jsonrpc::method_ident!($name)),*]
27    };
28}
29
30mod container;
31mod registry;
32
33/// Error code for parse errors in JSON-RPC.
34const PARSE_ERROR: i32 = -32700;
35
36/// Error code for method not found in JSON-RPC.
37const METHOD_NOT_FOUND: i32 = -32601;
38
39/// Error code for invalid parameters in JSON-RPC.
40pub const INVALID_PARAMS: i32 = -32602;
41
42/// Error code for server errors in JSON-RPC.
43const SERVER_ERROR: i32 = -32000;
44
45/// Represents a JSON-RPC request.
46#[derive(Deserialize, Debug)]
47pub struct Request<'a> {
48    /// JSON-RPC version.
49    #[allow(dead_code)]
50    jsonrpc: V2_0,
51
52    /// Method name.
53    pub method: &'a str,
54
55    /// Parameters.
56    #[serde(borrow)]
57    pub params: Option<&'a RawValue>,
58    #[serde(borrow, default)]
59
60    /// Request ID.
61    pub id: Id<'a>,
62}
63
64/// Represents a JSON-RPC response.
65#[derive(Serialize, Debug)]
66pub struct Response<'a> {
67    /// JSON-RPC version.
68    jsonrpc: V2_0,
69
70    /// Result of the method invocation.
71    #[serde(skip_serializing_if = "Option::is_none")]
72    pub result: Option<Value>,
73
74    /// Error occurred during method invocation.
75    #[serde(skip_serializing_if = "Option::is_none")]
76    pub error: Option<Error>,
77
78    /// Response ID.
79    pub id: Id<'a>,
80}
81
82impl<'a> Response<'a> {
83    /// Creates a successful JSON-RPC response.
84    pub fn result(result: Value, id: Id<'a>) -> Self {
85        Self {
86            jsonrpc: V2_0,
87            result: Some(result),
88            error: None,
89            id,
90        }
91    }
92
93    /// Creates an error JSON-RPC response.
94    pub fn error(err: Error, id: Id<'a>) -> Self {
95        Self {
96            jsonrpc: V2_0,
97            result: None,
98            error: Some(err),
99            id,
100        }
101    }
102}
103
104/// Represents a JSON-RPC error.
105#[derive(Serialize, Debug, Clone)]
106pub struct Error {
107    /// Error code.
108    pub code: i32,
109
110    /// Error message.
111    pub message: String,
112
113    /// Additional data associated with the error.
114    pub data: Option<Value>,
115}
116
117impl Display for Error {
118    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
119        f.write_str(&self.message)
120    }
121}
122
123impl StdError for Error {}
124
125impl Error {
126    /// Creates a new JSON-RPC error.
127    pub fn new(code: i32, message: impl ToString, data: Option<Value>) -> Self {
128        Self {
129            code,
130            message: message.to_string(),
131            data,
132        }
133    }
134
135    /// Casts a general error trait object to a specific JSON-RPC error.
136    pub fn cast<'a>(err: &'a (dyn StdError + 'static)) -> Option<&'a Self> {
137        match err.downcast_ref() {
138            Some(v) => return Some(v),
139            None => (),
140        };
141
142        let mut err: &(dyn StdError + 'static) = err;
143        while let Some(e) = err.source() {
144            match e.downcast_ref::<Self>() {
145                Some(e) => return Some(e),
146                None => err = e,
147            }
148        }
149        None
150    }
151}
152
153/// Represents the JSON-RPC version.
154#[derive(Copy, Clone, Debug)]
155struct V2_0;
156
157impl Serialize for V2_0 {
158    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
159    where
160        S: Serializer,
161    {
162        serializer.serialize_str("2.0")
163    }
164}
165
166impl<'a> Deserialize<'a> for V2_0 {
167    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
168    where
169        D: Deserializer<'a>,
170    {
171        match <&str as Deserialize>::deserialize(deserializer)? {
172            "2.0" => Ok(V2_0),
173            v => Err(SerdeError::invalid_value(Unexpected::Str(v), &"\"2.0\"")),
174        }
175    }
176}
177
178/// Represents various forms of JSON-RPC request IDs.
179#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
180#[serde(untagged)]
181pub enum Id<'a> {
182    /// String ID.
183    Str(&'a str),
184
185    /// Integer ID.
186    Int(i64),
187
188    /// Represents a null ID.
189    Null,
190
191    /// Represents an unspecified or missing ID.
192    None,
193}
194
195impl<'a> Default for Id<'a> {
196    fn default() -> Self {
197        Self::None
198    }
199}