cln_rpc/
jsonrpc.rs

1//! Common structs to handle JSON-RPC decoding and encoding. They are
2//! generic over the Notification and Request types.
3
4use serde::ser::{SerializeStruct, Serializer};
5use serde::de::{self, Deserializer};
6use serde::{Deserialize, Serialize};
7use serde_json::Value;
8use std::fmt::Debug;
9
10#[derive(Debug)]
11pub enum JsonRpc<N, R> {
12    Request(serde_json::Value, R),
13    Notification(N),
14}
15
16/// This function disentangles the various cases:
17///
18///   1) If we have an `id` then it is a request
19///
20///   2) Otherwise it's a notification that doesn't require a
21///   response.
22///
23/// Furthermore we distinguish between the built-in types and the
24/// custom user notifications/methods:
25///
26///   1) We either match a built-in type above,
27///
28///   2) Or it's a custom one, so we pass it around just as a
29///   `serde_json::Value`
30impl<'de, N, R> Deserialize<'de> for JsonRpc<N, R>
31where
32    N: Deserialize<'de> + Debug,
33    R: Deserialize<'de> + Debug,
34{
35    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
36    where
37        D: Deserializer<'de>,
38    {
39        #[derive(Deserialize, Debug)]
40        struct IdHelper {
41            id: Option<serde_json::Value>,
42        }
43
44        let v = Value::deserialize(deserializer)?;
45        let helper = IdHelper::deserialize(&v).map_err(de::Error::custom)?;
46        match helper.id {
47            Some(id) => {
48                let r = R::deserialize(v).map_err(de::Error::custom)?;
49                Ok(JsonRpc::Request(id, r))
50            }
51            None => {
52                let n = N::deserialize(v).map_err(de::Error::custom)?;
53                Ok(JsonRpc::Notification(n))
54            }
55        }
56    }
57}
58
59impl<N, R> Serialize for JsonRpc<N, R>
60where
61    N: Serialize + Debug,
62    R: Serialize + Debug,
63{
64    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
65    where
66        S: Serializer,
67    {
68        match self {
69            JsonRpc::Notification(r) => {
70                let r = serde_json::to_value(r).unwrap();
71                let mut s = serializer.serialize_struct("Notification", 3)?;
72                s.serialize_field("jsonrpc", "2.0")?;
73                s.serialize_field("method", &r["method"])?;
74                s.serialize_field("params", &r["params"])?;
75                s.end()
76            }
77            JsonRpc::Request(id, r) => {
78                let r = serde_json::to_value(r).unwrap();
79                let mut s = serializer.serialize_struct("Request", 4)?;
80                s.serialize_field("jsonrpc", "2.0")?;
81                s.serialize_field("id", id)?;
82                s.serialize_field("method", &r["method"])?;
83                s.serialize_field("params", &r["params"])?;
84                s.end()
85            }
86        }
87    }
88}