1use crate::{common::Id, RpcSend};
2use serde::{
3 de::{DeserializeOwned, MapAccess, Visitor},
4 ser::SerializeMap,
5 Deserialize, Deserializer, Serialize,
6};
7use serde_json::value::RawValue;
8use std::{
9 borrow::{Borrow, Cow},
10 fmt,
11 marker::PhantomData,
12};
13
14mod error;
15pub use error::{BorrowedErrorPayload, ErrorPayload};
16
17mod payload;
18pub use payload::{BorrowedResponsePayload, ResponsePayload};
19
20#[derive(Clone, Debug)]
27pub struct Response<Payload = Box<RawValue>, ErrData = Box<RawValue>> {
28 pub id: Id,
30 pub payload: ResponsePayload<Payload, ErrData>,
32}
33
34pub type BorrowedResponse<'a> = Response<&'a RawValue, &'a RawValue>;
42
43impl BorrowedResponse<'_> {
44 pub fn into_owned(self) -> Response {
47 Response { id: self.id.clone(), payload: self.payload.into_owned() }
48 }
49}
50
51impl<Payload, ErrData> Response<Payload, ErrData> {
52 pub const fn parse_error(id: Id) -> Self {
54 Self { id, payload: ResponsePayload::parse_error() }
55 }
56
57 pub const fn invalid_request(id: Id) -> Self {
59 Self { id, payload: ResponsePayload::invalid_request() }
60 }
61
62 pub const fn method_not_found(id: Id) -> Self {
64 Self { id, payload: ResponsePayload::method_not_found() }
65 }
66
67 pub const fn invalid_params(id: Id) -> Self {
69 Self { id, payload: ResponsePayload::invalid_params() }
70 }
71
72 pub const fn internal_error(id: Id) -> Self {
74 Self { id, payload: ResponsePayload::internal_error() }
75 }
76
77 pub const fn internal_error_message(id: Id, message: Cow<'static, str>) -> Self {
79 Self {
80 id,
81 payload: ResponsePayload::Failure(ErrorPayload::internal_error_message(message)),
82 }
83 }
84
85 pub const fn internal_error_with_obj(id: Id, data: ErrData) -> Self
87 where
88 ErrData: RpcSend,
89 {
90 Self { id, payload: ResponsePayload::Failure(ErrorPayload::internal_error_with_obj(data)) }
91 }
92
93 pub const fn internal_error_with_message_and_obj(
96 id: Id,
97 message: Cow<'static, str>,
98 data: ErrData,
99 ) -> Self
100 where
101 ErrData: RpcSend,
102 {
103 Self {
104 id,
105 payload: ResponsePayload::Failure(ErrorPayload::internal_error_with_message_and_obj(
106 message, data,
107 )),
108 }
109 }
110
111 pub const fn is_success(&self) -> bool {
113 self.payload.is_success()
114 }
115
116 pub const fn is_error(&self) -> bool {
118 self.payload.is_error()
119 }
120}
121
122impl<Payload, ErrData> Response<Payload, ErrData>
123where
124 Payload: RpcSend,
125 ErrData: RpcSend,
126{
127 pub fn serialize_payload(&self) -> serde_json::Result<Response> {
129 self.payload.serialize_payload().map(|payload| Response { id: self.id.clone(), payload })
130 }
131}
132
133impl<'a, Payload, ErrData> Response<Payload, ErrData>
134where
135 Payload: AsRef<RawValue> + 'a,
136{
137 pub fn try_success_as<T: Deserialize<'a>>(&'a self) -> Option<serde_json::Result<T>> {
142 self.payload.try_success_as()
143 }
144
145 pub fn deser_success<T: DeserializeOwned>(self) -> Result<Response<T, ErrData>, Self> {
153 match self.payload.deserialize_success() {
154 Ok(payload) => Ok(Response { id: self.id, payload }),
155 Err(payload) => Err(Self { id: self.id, payload }),
156 }
157 }
158}
159
160impl<'a, Payload, ErrData> Response<Payload, ErrData>
161where
162 ErrData: Borrow<RawValue> + 'a,
163{
164 pub fn try_error_as<T: Deserialize<'a>>(&'a self) -> Option<serde_json::Result<T>> {
169 self.payload.try_error_as()
170 }
171
172 pub fn deser_err<T: DeserializeOwned>(self) -> Result<Response<Payload, T>, Self> {
180 match self.payload.deserialize_error() {
181 Ok(payload) => Ok(Response { id: self.id, payload }),
182 Err(payload) => Err(Self { id: self.id, payload }),
183 }
184 }
185}
186
187impl<'de, Payload, ErrData> Deserialize<'de> for Response<Payload, ErrData>
188where
189 Payload: Deserialize<'de>,
190 ErrData: Deserialize<'de>,
191{
192 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
193 where
194 D: serde::Deserializer<'de>,
195 {
196 enum Field {
197 Result,
198 Error,
199 Id,
200 Unknown,
201 }
202
203 impl<'de> Deserialize<'de> for Field {
204 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
205 where
206 D: Deserializer<'de>,
207 {
208 struct FieldVisitor;
209
210 impl serde::de::Visitor<'_> for FieldVisitor {
211 type Value = Field;
212
213 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
214 formatter.write_str("`result`, `error` and `id`")
215 }
216
217 fn visit_str<E>(self, value: &str) -> Result<Field, E>
218 where
219 E: serde::de::Error,
220 {
221 match value {
222 "result" => Ok(Field::Result),
223 "error" => Ok(Field::Error),
224 "id" => Ok(Field::Id),
225 _ => Ok(Field::Unknown),
226 }
227 }
228 }
229 deserializer.deserialize_identifier(FieldVisitor)
230 }
231 }
232
233 struct JsonRpcResponseVisitor<T>(PhantomData<T>);
234
235 impl<'de, Payload, ErrData> Visitor<'de> for JsonRpcResponseVisitor<fn() -> (Payload, ErrData)>
236 where
237 Payload: Deserialize<'de>,
238 ErrData: Deserialize<'de>,
239 {
240 type Value = Response<Payload, ErrData>;
241
242 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
243 formatter.write_str(
244 "a JSON-RPC response object, consisting of either a result or an error",
245 )
246 }
247
248 fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
249 where
250 M: MapAccess<'de>,
251 {
252 let mut result = None;
253 let mut error = None;
254 let mut id: Option<Id> = None;
255
256 while let Some(key) = map.next_key()? {
257 match key {
258 Field::Result => {
259 if result.is_some() {
260 return Err(serde::de::Error::duplicate_field("result"));
261 }
262 result = Some(map.next_value()?);
263 }
264 Field::Error => {
265 if error.is_some() {
266 return Err(serde::de::Error::duplicate_field("error"));
267 }
268 error = Some(map.next_value()?);
269 }
270 Field::Id => {
271 if id.is_some() {
272 return Err(serde::de::Error::duplicate_field("id"));
273 }
274 id = Some(map.next_value()?);
275 }
276 Field::Unknown => {
277 let _: serde::de::IgnoredAny = map.next_value()?; }
279 }
280 }
281 let id = id.unwrap_or(Id::None);
282
283 match (result, error) {
284 (Some(result), None) => {
285 Ok(Response { id, payload: ResponsePayload::Success(result) })
286 }
287 (None, Some(error)) => {
288 Ok(Response { id, payload: ResponsePayload::Failure(error) })
289 }
290 (None, None) => Err(serde::de::Error::missing_field("result or error")),
291 (Some(_), Some(_)) => {
292 Err(serde::de::Error::custom("result and error are mutually exclusive"))
293 }
294 }
295 }
296 }
297
298 deserializer.deserialize_map(JsonRpcResponseVisitor(PhantomData))
299 }
300}
301
302impl<Payload, ErrData> Serialize for Response<Payload, ErrData>
303where
304 Payload: Serialize,
305 ErrData: Serialize,
306{
307 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
308 where
309 S: serde::Serializer,
310 {
311 let mut map = serializer.serialize_map(Some(3))?;
312 map.serialize_entry("jsonrpc", "2.0")?;
313 map.serialize_entry("id", &self.id)?;
314 match &self.payload {
315 ResponsePayload::Success(result) => {
316 map.serialize_entry("result", result)?;
317 }
318 ResponsePayload::Failure(error) => {
319 map.serialize_entry("error", error)?;
320 }
321 }
322 map.end()
323 }
324}
325
326#[cfg(test)]
327mod test {
328 #[test]
329 fn deser_success() {
330 let response = r#"{
331 "jsonrpc": "2.0",
332 "result": "california",
333 "id": 1
334 }"#;
335 let response: super::Response = serde_json::from_str(response).unwrap();
336 assert_eq!(response.id, super::Id::Number(1));
337 assert!(matches!(response.payload, super::ResponsePayload::Success(_)));
338 }
339
340 #[test]
341 fn deser_err() {
342 let response = r#"{
343 "jsonrpc": "2.0",
344 "error": {
345 "code": -32600,
346 "message": "Invalid Request"
347 },
348 "id": null
349 }"#;
350 let response: super::Response = serde_json::from_str(response).unwrap();
351 assert_eq!(response.id, super::Id::None);
352 assert!(matches!(response.payload, super::ResponsePayload::Failure(_)));
353 }
354
355 #[test]
356 fn deser_complex_success() {
357 let response = r#"{
358 "result": {
359 "name": "california",
360 "population": 39250000,
361 "cities": [
362 "los angeles",
363 "san francisco"
364 ]
365 }
366 }"#;
367 let response: super::Response = serde_json::from_str(response).unwrap();
368 assert_eq!(response.id, super::Id::None);
369 assert!(matches!(response.payload, super::ResponsePayload::Success(_)));
370 }
371}
372
373