jsonrpc_reactor/
impls.rs

1use alloc::string::{String, ToString};
2use alloc::vec::Vec;
3use core::{fmt, iter};
4
5use serde::de::Error as _;
6use serde::{Deserialize, Serialize};
7use serde_json::{json, Map, Value};
8
9use super::*;
10
11impl fmt::Display for Error {
12    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13        <Error as fmt::Debug>::fmt(self, f)
14    }
15}
16
17#[cfg(feature = "std")]
18impl std::error::Error for Error {}
19
20impl From<Id> for Value {
21    fn from(id: Id) -> Self {
22        match id {
23            Id::String(s) => Value::String(s),
24            Id::Number(n) => Value::Number(n.into()),
25        }
26    }
27}
28
29impl From<&Id> for Value {
30    fn from(id: &Id) -> Self {
31        match id {
32            Id::String(s) => Value::String(s.clone()),
33            Id::Number(n) => Value::Number((*n).into()),
34        }
35    }
36}
37
38impl From<String> for Id {
39    fn from(s: String) -> Self {
40        Self::String(s)
41    }
42}
43
44impl From<i64> for Id {
45    fn from(n: i64) -> Self {
46        Self::Number(n)
47    }
48}
49
50impl TryFrom<Value> for Id {
51    type Error = Error;
52
53    fn try_from(value: Value) -> Result<Self, Self::Error> {
54        match value {
55            Value::Number(n) => Ok(n.as_i64().ok_or(Error::InvalidNumberCast)?.into()),
56            Value::String(s) => Ok(s.into()),
57            Value::Null | Value::Array(_) | Value::Object(_) | Value::Bool(_) => {
58                Err(Error::UnexpectedIdVariant)
59            }
60        }
61    }
62}
63
64impl TryFrom<&Value> for Id {
65    type Error = Error;
66
67    fn try_from(value: &Value) -> Result<Self, Self::Error> {
68        match value {
69            Value::Number(n) => Ok(n.as_i64().ok_or(Error::InvalidNumberCast)?.into()),
70            Value::String(s) => Ok(s.clone().into()),
71            Value::Null | Value::Array(_) | Value::Object(_) | Value::Bool(_) => {
72                Err(Error::UnexpectedIdVariant)
73            }
74        }
75    }
76}
77
78impl Serialize for Id {
79    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
80    where
81        S: serde::Serializer,
82    {
83        Value::from(self).serialize(serializer)
84    }
85}
86
87impl<'de> Deserialize<'de> for Id {
88    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
89    where
90        D: serde::Deserializer<'de>,
91    {
92        Value::deserialize(deserializer).and_then(|v| Self::try_from(v).map_err(D::Error::custom))
93    }
94}
95
96impl Params {
97    pub fn as_array(&self) -> Option<&[Value]> {
98        match self {
99            Params::Array(a) => Some(a),
100            _ => None,
101        }
102    }
103
104    pub fn as_object(&self) -> Option<&Map<String, Value>> {
105        match self {
106            Params::Object(m) => Some(m),
107            _ => None,
108        }
109    }
110}
111
112impl From<Params> for Value {
113    fn from(params: Params) -> Self {
114        match params {
115            Params::Array(a) => Value::Array(a),
116            Params::Object(m) => Value::Object(m),
117            Params::Null => Value::Null,
118        }
119    }
120}
121
122impl From<&Params> for Value {
123    fn from(params: &Params) -> Self {
124        match params {
125            Params::Array(a) => Value::Array(a.clone()),
126            Params::Object(m) => Value::Object(m.clone()),
127            Params::Null => Value::Null,
128        }
129    }
130}
131
132impl From<Vec<Value>> for Params {
133    fn from(a: Vec<Value>) -> Self {
134        Self::Array(a)
135    }
136}
137
138impl From<Map<String, Value>> for Params {
139    fn from(m: Map<String, Value>) -> Self {
140        Self::Object(m)
141    }
142}
143
144impl FromIterator<Value> for Params {
145    fn from_iter<T: IntoIterator<Item = Value>>(iter: T) -> Self {
146        iter.into_iter().collect::<Vec<_>>().into()
147    }
148}
149
150impl FromIterator<(String, Value)> for Params {
151    fn from_iter<T: IntoIterator<Item = (String, Value)>>(iter: T) -> Self {
152        iter.into_iter().collect::<Map<_, _>>().into()
153    }
154}
155
156impl TryFrom<Value> for Params {
157    type Error = Error;
158
159    fn try_from(value: Value) -> Result<Self, Self::Error> {
160        match value {
161            Value::Null => Ok(Self::Null),
162            Value::Array(a) => Ok(a.into()),
163            Value::Object(o) => Ok(o.into()),
164
165            Value::Bool(_) | Value::Number(_) | Value::String(_) => {
166                Err(Error::UnexpectedParamsVariant)
167            }
168        }
169    }
170}
171
172impl TryFrom<&Value> for Params {
173    type Error = Error;
174
175    fn try_from(value: &Value) -> Result<Self, Self::Error> {
176        match value {
177            Value::Null => Ok(Self::Null),
178            Value::Array(a) => Ok(a.clone().into()),
179            Value::Object(o) => Ok(o.clone().into()),
180
181            Value::Bool(_) | Value::Number(_) | Value::String(_) => {
182                Err(Error::UnexpectedParamsVariant)
183            }
184        }
185    }
186}
187
188impl Serialize for Params {
189    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
190    where
191        S: serde::Serializer,
192    {
193        Value::from(self).serialize(serializer)
194    }
195}
196
197impl<'de> Deserialize<'de> for Params {
198    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
199    where
200        D: serde::Deserializer<'de>,
201    {
202        Value::deserialize(deserializer).and_then(|v| Self::try_from(v).map_err(D::Error::custom))
203    }
204}
205
206impl From<Request> for Value {
207    fn from(req: Request) -> Self {
208        let Request { id, method, params } = req;
209        let params = Value::from(params);
210
211        let map = iter::once(Some((
212            "jsonrpc".to_string(),
213            Value::String("2.0".to_string()),
214        )))
215        .chain(iter::once(Some(("method".to_string(), method.into()))))
216        .chain(iter::once(
217            (!params.is_null()).then(|| ("params".to_string(), params)),
218        ))
219        .chain(iter::once(Some(("id".to_string(), id.into()))))
220        .flatten()
221        .collect();
222
223        Value::Object(map)
224    }
225}
226
227impl TryFrom<&Value> for Request {
228    type Error = Error;
229
230    fn try_from(value: &Value) -> Result<Self, Self::Error> {
231        let map = value.as_object().ok_or(Error::UnexpectedRequestVariant)?;
232
233        map.get("jsonrpc")
234            .ok_or(Error::JsonRpcVersionNotFound)?
235            .as_str()
236            .filter(|version| version == &"2.0")
237            .ok_or(Error::InvalidJsonRpcVersion)?;
238
239        let id = map.get("id").ok_or(Error::ExpectedId)?.try_into()?;
240
241        let method = map
242            .get("method")
243            .ok_or(Error::ExpectedMethod)?
244            .as_str()
245            .ok_or(Error::InvalidMethodVariant)?
246            .to_string();
247
248        let params = map.get("params").unwrap_or(&Value::Null).try_into()?;
249
250        Ok(Self { id, method, params })
251    }
252}
253
254impl From<Notification> for Value {
255    fn from(notification: Notification) -> Self {
256        let Notification { method, params } = notification;
257
258        let method = Value::String(method);
259        let params = Value::from(params);
260
261        json!({
262            "jsonrpc": "2.0",
263            "method": method,
264            "params": params,
265        })
266    }
267}
268
269impl TryFrom<&Value> for Notification {
270    type Error = Error;
271
272    fn try_from(value: &Value) -> Result<Self, Self::Error> {
273        let map = value.as_object().ok_or(Error::UnexpectedRequestVariant)?;
274
275        map.get("jsonrpc")
276            .ok_or(Error::JsonRpcVersionNotFound)?
277            .as_str()
278            .filter(|version| version == &"2.0")
279            .ok_or(Error::InvalidJsonRpcVersion)?;
280
281        let method = map
282            .get("method")
283            .ok_or(Error::ExpectedMethod)?
284            .as_str()
285            .ok_or(Error::InvalidMethodVariant)?
286            .to_string();
287
288        let params = map.get("params").unwrap_or(&Value::Null).try_into()?;
289
290        Ok(Self { method, params })
291    }
292}
293
294impl fmt::Display for RpcError {
295    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
296        self.message.fmt(f)
297    }
298}
299
300#[cfg(feature = "std")]
301impl std::error::Error for RpcError {}
302
303impl From<RpcError> for Value {
304    fn from(re: RpcError) -> Self {
305        json!({
306            "code": re.code,
307            "message": re.message,
308            "data": re.data,
309        })
310    }
311}
312
313impl From<&RpcError> for Value {
314    fn from(re: &RpcError) -> Self {
315        json!({
316            "code": re.code,
317            "message": re.message,
318            "data": re.data,
319        })
320    }
321}
322
323impl TryFrom<Value> for RpcError {
324    type Error = Error;
325
326    fn try_from(value: Value) -> Result<Self, Self::Error> {
327        let map = value.as_object().ok_or(Error::UnexpectedErrorVariant)?;
328
329        let code = map
330            .get("code")
331            .ok_or(Error::ExpectedErrorCode)?
332            .as_i64()
333            .ok_or(Error::ExpectedErrorCodeAsInteger)?;
334
335        let message = map
336            .get("message")
337            .ok_or(Error::ExpectedErrorMessage)?
338            .as_str()
339            .ok_or(Error::ExpectedErrorCodeAsString)?
340            .to_string();
341
342        let data = map.get("data").unwrap_or(&Value::Null).clone();
343
344        Ok(Self {
345            code,
346            message,
347            data,
348        })
349    }
350}
351
352impl TryFrom<&Value> for RpcError {
353    type Error = Error;
354
355    fn try_from(value: &Value) -> Result<Self, Self::Error> {
356        let map = value.as_object().ok_or(Error::UnexpectedErrorVariant)?;
357
358        let code = map
359            .get("code")
360            .ok_or(Error::ExpectedErrorCode)?
361            .as_i64()
362            .ok_or(Error::ExpectedErrorCodeAsInteger)?;
363
364        let message = map
365            .get("message")
366            .ok_or(Error::ExpectedErrorMessage)?
367            .as_str()
368            .ok_or(Error::ExpectedErrorCodeAsString)?
369            .to_string();
370
371        let data = map.get("data").unwrap_or(&Value::Null).clone();
372
373        Ok(Self {
374            code,
375            message,
376            data,
377        })
378    }
379}
380
381impl Serialize for RpcError {
382    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
383    where
384        S: serde::Serializer,
385    {
386        Value::from(self).serialize(serializer)
387    }
388}
389
390impl<'de> Deserialize<'de> for RpcError {
391    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
392    where
393        D: serde::Deserializer<'de>,
394    {
395        Value::deserialize(deserializer).and_then(|v| Self::try_from(v).map_err(D::Error::custom))
396    }
397}
398
399impl From<Response> for Value {
400    fn from(response: Response) -> Self {
401        let Response { id, result } = response;
402
403        let result = result
404            .map(|v| Some(("result".to_string(), v)))
405            .unwrap_or_else(|e| Some(("error".to_string(), Value::from(e))));
406
407        let map = iter::once(Some((
408            "jsonrpc".to_string(),
409            Value::String("2.0".to_string()),
410        )))
411        .chain(iter::once(Some(("id".to_string(), id.into()))))
412        .chain(iter::once(result))
413        .flatten()
414        .collect();
415
416        Value::Object(map)
417    }
418}
419
420impl From<&Response> for Value {
421    fn from(response: &Response) -> Self {
422        let Response { id, result } = response;
423
424        let result = result
425            .as_ref()
426            .map(|v| Some(("result".to_string(), v.clone())))
427            .unwrap_or_else(|e| Some(("error".to_string(), Value::from(e.clone()))));
428
429        let map = iter::once(Some((
430            "jsonrpc".to_string(),
431            Value::String("2.0".to_string()),
432        )))
433        .chain(iter::once(Some(("id".to_string(), id.into()))))
434        .chain(iter::once(result))
435        .flatten()
436        .collect();
437
438        Value::Object(map)
439    }
440}
441
442impl TryFrom<Value> for Response {
443    type Error = Error;
444
445    fn try_from(value: Value) -> Result<Self, Self::Error> {
446        let map = value.as_object().ok_or(Error::UnexpectedResponseVariant)?;
447
448        map.get("jsonrpc")
449            .ok_or(Error::JsonRpcVersionNotFound)?
450            .as_str()
451            .filter(|version| version == &"2.0")
452            .ok_or(Error::InvalidJsonRpcVersion)?;
453
454        let result = map.get("result").cloned();
455        let error = map.get("error").map(RpcError::try_from).transpose()?;
456
457        let result = match (result, error) {
458            (None, Some(e)) => Err(e),
459            (Some(v), None) => Ok(v),
460            (Some(_), Some(_)) | (None, None) => return Err(Error::ResponseExpectsResultOrError),
461        };
462
463        let id = map.get("id").ok_or(Error::ExpectedId)?.try_into()?;
464
465        Ok(Self { id, result })
466    }
467}
468
469impl TryFrom<&Value> for Response {
470    type Error = Error;
471
472    fn try_from(value: &Value) -> Result<Self, Self::Error> {
473        let map = value.as_object().ok_or(Error::UnexpectedResponseVariant)?;
474
475        map.get("jsonrpc")
476            .ok_or(Error::JsonRpcVersionNotFound)?
477            .as_str()
478            .filter(|version| version == &"2.0")
479            .ok_or(Error::InvalidJsonRpcVersion)?;
480
481        let result = map.get("result").cloned();
482        let error = map.get("error").map(RpcError::try_from).transpose()?;
483
484        let result = match (result, error) {
485            (None, Some(e)) => Err(e),
486            (Some(v), None) => Ok(v),
487            (Some(_), Some(_)) | (None, None) => return Err(Error::ResponseExpectsResultOrError),
488        };
489
490        let id = map.get("id").ok_or(Error::ExpectedId)?.try_into()?;
491
492        Ok(Self { id, result })
493    }
494}
495
496impl Serialize for Response {
497    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
498    where
499        S: serde::Serializer,
500    {
501        Value::from(self).serialize(serializer)
502    }
503}
504
505impl<'de> Deserialize<'de> for Response {
506    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
507    where
508        D: serde::Deserializer<'de>,
509    {
510        Value::deserialize(deserializer).and_then(|v| Self::try_from(v).map_err(D::Error::custom))
511    }
512}