1use serde::de::{Deserialize, Deserializer, Error as DeError};
3use serde::ser::{Serialize, Serializer};
4use serde_json::value::from_value;
5use super::{Id, Value, Error, ErrorCode, Version};
6use {Result as CoreResult};
7
8#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
10pub struct Success {
11 #[serde(skip_serializing_if = "Option::is_none")]
13 pub jsonrpc: Option<Version>,
14 pub result: Value,
16 pub id: Id
18}
19
20#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
22pub struct Failure {
23 #[serde(skip_serializing_if = "Option::is_none")]
25 pub jsonrpc: Option<Version>,
26 pub error: Error,
28 pub id: Id
30}
31
32#[derive(Debug, PartialEq, Clone)]
34pub enum Output {
35 Success(Success),
37 Failure(Failure),
39}
40
41impl Output {
42 pub fn from(result: CoreResult<Value>, id: Id, jsonrpc: Option<Version>) -> Self {
44 match result {
45 Ok(result) => Output::Success(Success {
46 id: id,
47 jsonrpc: jsonrpc,
48 result: result,
49 }),
50 Err(error) => Output::Failure(Failure {
51 id: id,
52 jsonrpc: jsonrpc,
53 error: error,
54 }),
55 }
56 }
57
58 pub fn invalid_request(id: Id, jsonrpc: Option<Version>) -> Self {
60 Output::Failure(Failure {
61 id: id,
62 jsonrpc: jsonrpc,
63 error: Error::new(ErrorCode::InvalidRequest),
64 })
65 }
66
67 pub fn version(&self) -> Option<Version> {
69 match *self {
70 Output::Success(ref s) => s.jsonrpc,
71 Output::Failure(ref f) => f.jsonrpc,
72 }
73 }
74
75 pub fn id(&self) -> &Id {
77 match *self {
78 Output::Success(ref s) => &s.id,
79 Output::Failure(ref f) => &f.id,
80 }
81 }
82}
83
84impl From<Output> for CoreResult<Value> {
85 fn from(output: Output) -> CoreResult<Value> {
87 match output {
88 Output::Success(s) => Ok(s.result),
89 Output::Failure(f) => Err(f.error),
90 }
91 }
92}
93
94impl<'a> Deserialize<'a> for Output {
95 fn deserialize<D>(deserializer: D) -> Result<Output, D::Error>
96 where D: Deserializer<'a> {
97 let v: Value = try!(Deserialize::deserialize(deserializer));
98 from_value(v.clone()).map(Output::Failure)
99 .or_else(|_| from_value(v).map(Output::Success))
100 .map_err(|_| D::Error::custom("")) }
102}
103
104impl Serialize for Output {
105 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
106 where S: Serializer {
107 match *self {
108 Output::Success(ref s) => s.serialize(serializer),
109 Output::Failure(ref f) => f.serialize(serializer)
110 }
111 }
112}
113
114#[derive(Debug, PartialEq)]
116pub enum Response {
117 Single(Output),
119 Batch(Vec<Output>)
121}
122
123impl<'a> Deserialize<'a> for Response {
124 fn deserialize<D>(deserializer: D) -> Result<Response, D::Error>
125 where D: Deserializer<'a> {
126 let v: Value = try!(Deserialize::deserialize(deserializer));
127 from_value(v.clone()).map(Response::Batch)
128 .or_else(|_| from_value(v).map(Response::Single))
129 .map_err(|_| D::Error::custom("")) }
131}
132
133impl Serialize for Response {
134 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
135 where S: Serializer {
136 match *self {
137 Response::Single(ref o) => o.serialize(serializer),
138 Response::Batch(ref b) => b.serialize(serializer)
139 }
140 }
141}
142
143impl Response {
144 pub fn from(error: Error, jsonrpc: Option<Version>) -> Self {
146 Failure {
147 id: Id::Null,
148 jsonrpc: jsonrpc,
149 error: error,
150 }.into()
151 }
152}
153
154impl From<Failure> for Response {
155 fn from(failure: Failure) -> Self {
156 Response::Single(Output::Failure(failure))
157 }
158}
159
160impl From<Success> for Response {
161 fn from(success: Success) -> Self {
162 Response::Single(Output::Success(success))
163 }
164}
165
166#[test]
167fn success_output_serialize() {
168 use serde_json;
169 use serde_json::Value;
170
171 let so = Output::Success(Success {
172 jsonrpc: Some(Version::V2),
173 result: Value::from(1),
174 id: Id::Num(1)
175 });
176
177 let serialized = serde_json::to_string(&so).unwrap();
178 assert_eq!(serialized, r#"{"jsonrpc":"2.0","result":1,"id":1}"#);
179}
180
181#[test]
182fn success_output_deserialize() {
183 use serde_json;
184 use serde_json::Value;
185
186 let dso = r#"{"jsonrpc":"2.0","result":1,"id":1}"#;
187
188 let deserialized: Output = serde_json::from_str(dso).unwrap();
189 assert_eq!(deserialized, Output::Success(Success {
190 jsonrpc: Some(Version::V2),
191 result: Value::from(1),
192 id: Id::Num(1)
193 }));
194}
195
196#[test]
197fn failure_output_serialize() {
198 use serde_json;
199
200 let fo = Output::Failure(Failure {
201 jsonrpc: Some(Version::V2),
202 error: Error::parse_error(),
203 id: Id::Num(1)
204 });
205
206 let serialized = serde_json::to_string(&fo).unwrap();
207 assert_eq!(serialized, r#"{"jsonrpc":"2.0","error":{"code":-32700,"message":"Parse error"},"id":1}"#);
208}
209
210#[test]
211fn failure_output_serialize_rs_jsonrpc_1() {
212 use serde_json;
213
214 let fo = Output::Failure(Failure {
215 jsonrpc: None,
216 error: Error::parse_error(),
217 id: Id::Num(1)
218 });
219
220 let serialized = serde_json::to_string(&fo).unwrap();
221 assert_eq!(serialized, r#"{"error":{"code":-32700,"message":"Parse error"},"id":1}"#);
222}
223
224#[test]
225fn failure_output_deserialize() {
226 use serde_json;
227
228 let dfo = r#"{"jsonrpc":"2.0","error":{"code":-32700,"message":"Parse error"},"id":1}"#;
229
230 let deserialized: Output = serde_json::from_str(dfo).unwrap();
231 assert_eq!(deserialized, Output::Failure(Failure {
232 jsonrpc: Some(Version::V2),
233 error: Error::parse_error(),
234 id: Id::Num(1)
235 }));
236}
237
238#[test]
239fn single_response_deserialize() {
240 use serde_json;
241 use serde_json::Value;
242
243 let dsr = r#"{"jsonrpc":"2.0","result":1,"id":1}"#;
244
245 let deserialized: Response = serde_json::from_str(dsr).unwrap();
246 assert_eq!(deserialized, Response::Single(Output::Success(Success {
247 jsonrpc: Some(Version::V2),
248 result: Value::from(1),
249 id: Id::Num(1)
250 })));
251}
252
253#[test]
254fn batch_response_deserialize() {
255 use serde_json;
256 use serde_json::Value;
257
258 let dbr = r#"[{"jsonrpc":"2.0","result":1,"id":1},{"jsonrpc":"2.0","error":{"code":-32700,"message":"Parse error"},"id":1}]"#;
259
260 let deserialized: Response = serde_json::from_str(dbr).unwrap();
261 assert_eq!(deserialized, Response::Batch(vec![
262 Output::Success(Success {
263 jsonrpc: Some(Version::V2),
264 result: Value::from(1),
265 id: Id::Num(1)
266 }),
267 Output::Failure(Failure {
268 jsonrpc: Some(Version::V2),
269 error: Error::parse_error(),
270 id: Id::Num(1)
271 })
272 ]));
273}