rs_jsonrpc_core/types/
response.rs

1//! jsonrpc response
2use 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/// Successful response
9#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
10pub struct Success {
11	/// Protocol version
12    #[serde(skip_serializing_if = "Option::is_none")]
13	pub jsonrpc: Option<Version>,
14	/// Result
15	pub result: Value,
16	/// Correlation id
17	pub id: Id
18}
19
20/// Unsuccessful response
21#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
22pub struct Failure {
23	/// Protocol Version
24    #[serde(skip_serializing_if = "Option::is_none")]
25	pub jsonrpc: Option<Version>,
26	/// Error
27	pub error: Error,
28	/// Correlation id
29	pub id: Id
30}
31
32/// Represents output - failure or success
33#[derive(Debug, PartialEq, Clone)]
34pub enum Output {
35	/// Success
36	Success(Success),
37	/// Failure
38	Failure(Failure),
39}
40
41impl Output {
42	/// Creates new output given `Result`, `Id` and `Version`.
43	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	/// Creates new failure output indicating malformed request.
59	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	/// Get the jsonrpc protocol version.
68	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	/// Get the correlation id.
76	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	/// Convert into a result. Will be `Ok` if it is a `Success` and `Err` if `Failure`.
86	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("")) // types must match
101	}
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/// Synchronous response
115#[derive(Debug, PartialEq)]
116pub enum Response {
117	/// Single response
118	Single(Output),
119	/// Response to batch request (batch of responses)
120	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("")) // types must match
130	}
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	/// Creates new `Response` with given error and `Version`
145	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}