json_rpc_types/
response.rs1use serde::{Deserialize, Deserializer, Serialize, Serializer};
2
3use crate::error::Error;
4use crate::version::Version;
5use crate::id::Id;
6use crate::utils::Key;
7
8use core::mem;
9
10#[derive(Clone, Debug, PartialEq)]
26pub struct Response<R, E, EM=crate::error::StrBuf> {
27 pub jsonrpc: Version,
29
30 pub payload: Result<R, Error<E, EM>>,
32
33 pub id: Option<Id>,
39}
40
41impl<R: Serialize, E: Serialize, EM: Serialize> Serialize for Response<R, E, EM> {
42 fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
43 use serde::ser::SerializeMap;
44
45 let mut state = ser.serialize_map(Some(3))?;
46
47 state.serialize_entry("jsonrpc", &self.jsonrpc)?;
48 match self.payload {
49 Ok(ref result) => state.serialize_entry("result", result),
50 Err(ref error) => state.serialize_entry("error", error),
51 }?;
52 match self.id {
53 Some(ref id) => state.serialize_entry("id", id),
54 None => state.serialize_entry("id", &()),
55 }?;
56
57 state.end()
58 }
59}
60
61impl<'de, R: Deserialize<'de>, E: Deserialize<'de>, EM: Deserialize<'de>> Deserialize<'de> for Response<R, E, EM> {
62 fn deserialize<D: Deserializer<'de>>(der: D) -> Result<Self, D::Error> {
63 use core::marker::PhantomData;
64 use serde::de::{self, Visitor};
65
66 struct MapVisit<R, E, EM>(PhantomData<(R, E, EM)>);
67
68 impl<'de, R: Deserialize<'de>, E: Deserialize<'de>, EM: Deserialize<'de>> Visitor<'de> for MapVisit<R, E, EM> {
69 type Value = Response<R, E, EM>;
70
71 #[inline]
72 fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
73 formatter.write_str("Object resembling JSON-RPC response type")
74 }
75
76 fn visit_map<A: de::MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> {
77 let mut version = None;
80 let mut result = None;
81 let mut id = None;
82
83 while let Some(key) = map.next_key::<Key>()? {
84 match key {
85 Key::JsonRpc => {
86 version = Some(map.next_value::<Version>()?);
87 },
88 Key::Result if mem::size_of::<R>() == 0 => {
93 if result.is_none() {
94 result = Some(Ok(map.next_value::<R>()?));
95 } else {
96 return Err(serde::de::Error::custom("JSON-RPC Response contains both result and error field"));
97 }
98 }
99 Key::Result => match map.next_value::<Option<R>>()? {
100 Some(value) => if result.is_none() {
101 result = Some(Ok(value));
102 } else {
103 return Err(serde::de::Error::custom("JSON-RPC Response contains both result and error field"));
104 }
105 None => continue,
106 },
107 Key::Error => match map.next_value::<Option<Error<E, EM>>>()? {
108 Some(error) => if result.is_none() {
109 result = Some(Err(error));
110 } else {
111 return Err(serde::de::Error::custom("JSON-RPC Response contains both error and result field"));
112 }
113 None => continue,
114 },
115 Key::Id => {
116 id = map.next_value::<Option<Id>>()?;
117 },
118 }
119 }
120
121 Ok(Self::Value {
122 jsonrpc: match version {
123 Some(version) => version,
124 None => Version::V2,
125 },
126 payload: match result {
127 Some(payload) => payload,
128 None => {
129 return Err(serde::de::Error::custom("JSON-RPC Response is missing either result or error field."));
130 }
131 },
132 id,
133 })
134 }
135 }
136
137 der.deserialize_map(MapVisit(PhantomData))
138 }
139}
140
141impl<R, E, EM> Response<R, E, EM> {
142 #[inline]
143 pub const fn result(jsonrpc: Version, result: R, id: Option<Id>) -> Self {
145 Self {
146 jsonrpc,
147 payload: Ok(result),
148 id,
149 }
150 }
151
152 #[inline]
153 pub const fn error(jsonrpc: Version, error: Error<E, EM>, id: Option<Id>) -> Self {
155 Self {
156 jsonrpc,
157 payload: Err(error),
158 id,
159 }
160 }
161}