1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use crate::error::Error;
use crate::version::Version;
use crate::id::Id;
#[derive(Clone, Debug, PartialEq)]
pub struct Response<R, E> {
pub jsonrpc: Version,
pub payload: Result<R, Error<E>>,
pub id: Option<Id>,
}
impl<R: Serialize, E: Serialize> Serialize for Response<R, E> {
fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
use serde::ser::SerializeMap;
let mut state = ser.serialize_map(Some(3))?;
state.serialize_entry("jsonrpc", &self.jsonrpc)?;
match self.payload {
Ok(ref result) => state.serialize_entry("result", result),
Err(ref error) => state.serialize_entry("error", error),
}?;
match self.id {
Some(ref id) => state.serialize_entry("id", id),
None => state.serialize_key("id"),
}?;
state.end()
}
}
impl<'de, R: Deserialize<'de>, E: Deserialize<'de>> Deserialize<'de> for Response<R, E> {
fn deserialize<D: Deserializer<'de>>(der: D) -> Result<Self, D::Error> {
use core::marker::PhantomData;
use serde::de::{self, Visitor};
struct MapVisit<R, E>(PhantomData<Result<R, E>>);
impl<'de, R: Deserialize<'de>, E: Deserialize<'de>> Visitor<'de> for MapVisit<R, E> {
type Value = Response<R, E>;
#[inline]
fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
formatter.write_str("Object resembling JSON-RPC response type")
}
fn visit_map<A: de::MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> {
let mut version = None;
let mut result = None;
let mut id = None;
while let Some(key) = map.next_key::<&'de str>()? {
match key {
"jsonrpc" => {
version = Some(map.next_value::<Version>()?);
},
"result" => if result.is_none() {
result = Some(Ok(map.next_value::<R>()?));
} else {
return Err(serde::de::Error::custom("JSON-RPC Response contains both result and error field"));
},
"error" => if result.is_none() {
result = Some(Err(map.next_value::<Error<E>>()?));
} else {
return Err(serde::de::Error::custom("JSON-RPC Response contains both error and result field"));
},
"id" => {
id = map.next_value::<Option<Id>>()?;
},
unknown => {
return Err(serde::de::Error::custom(format_args!("JSON-RPC Response contains unknown field {}", unknown)));
}
}
}
Ok(Self::Value {
jsonrpc: match version {
Some(version) => version,
None => Version::V2,
},
payload: match result {
Some(payload) => payload,
None => return Err(serde::de::Error::custom("JSON-RPC Response is missing either result or error field.")),
},
id,
})
}
}
der.deserialize_map(MapVisit(PhantomData))
}
}
impl<R, E> Response<R, E> {
#[inline]
pub const fn result(jsonrpc: Version, result: R, id: Option<Id>) -> Self {
Self {
jsonrpc,
payload: Ok(result),
id,
}
}
#[inline]
pub const fn error(jsonrpc: Version, error: Error<E>, id: Option<Id>) -> Self {
Self {
jsonrpc,
payload: Err(error),
id,
}
}
}