1#![recursion_limit = "2048"]
2
3#[macro_use]
4extern crate serde_derive;
5
6pub use ezjsonrpc_macros::*;
7
8use std::borrow::{Borrow, Cow};
9
10use futures::{
11 future::{ok as future_ok, Either as EitherFuture},
12 Future
13};
14
15use proc_macro_hack::proc_macro_hack;
16use serde::{Deserialize, Deserializer, Serialize, Serializer};
17use serde_json::Value;
18
19#[proc_macro_hack]
20pub use ezjsonrpc_macros::methods;
21
22#[derive(Default, Debug)]
23pub struct V2;
24
25impl Serialize for V2 {
26 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
27 where S: Serializer {
28 "2.0".serialize(serializer)
29 }
30}
31
32impl<'de> Deserialize<'de> for V2 {
33 fn deserialize<D>(deserializer: D) -> Result<V2, D::Error>
34 where D: Deserializer<'de> {
35 let s: std::borrow::Cow<str> = Deserialize::deserialize(deserializer)?;
36 if s == "2.0" {
37 Ok(V2)
38 } else {
39 Err(serde::de::Error::custom("Could not deserialize V2"))
40 }
41 }
42}
43
44#[derive(Debug, Clone)]
45pub enum Id {
46 Num(i64),
47 Str(Cow<'static, str>),
48 Null
49}
50
51impl From<i64> for Id {
52 fn from(t: i64) -> Self { Id::Num(t) }
53}
54
55impl From<String> for Id {
56 fn from(t: String) -> Self { Id::Str(t.into()) }
57}
58
59impl From<&'static str> for Id {
60 fn from(t: &'static str) -> Self { Id::Str(t.into()) }
61}
62
63impl Default for Id {
64 fn default() -> Id { Id::Null }
65}
66
67impl Serialize for Id {
68 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
69 where S: Serializer {
70 match *self {
71 Id::Num(ref num) => num.serialize(serializer),
72 Id::Str(ref s) => s.serialize(serializer),
73 Id::Null => serializer.serialize_none()
74 }
75 }
76}
77
78impl<'de> Deserialize<'de> for Id {
79 fn deserialize<D>(deserializer: D) -> Result<Id, D::Error>
80 where D: Deserializer<'de> {
81 #[derive(Serialize, Deserialize)]
82 #[serde(untagged)]
83 pub enum PresentId {
84 Num(i64),
85 Str(Cow<'static, str>)
86 }
87
88 #[derive(Serialize, Deserialize)]
89 pub struct WrappedPresentId(Option<PresentId>);
90
91 let out = match WrappedPresentId::deserialize(deserializer)? {
92 WrappedPresentId(Some(PresentId::Num(num))) => Id::Num(num),
93 WrappedPresentId(Some(PresentId::Str(s))) => Id::Str(s),
94 WrappedPresentId(None) => Id::Null
95 };
96
97 Ok(out)
98 }
99}
100
101#[derive(Serialize, Deserialize, Debug)]
102#[serde(untagged)]
103pub enum RequestObject {
104 Request { jsonrpc: V2, method: Cow<'static, str>, params: Option<Value>, id: Id },
105 Notification { jsonrpc: V2, method: Cow<'static, str>, params: Option<Value> }
106}
107
108impl RequestObject {
109 pub fn with_id<I: Into<Id>>(self, id: I) -> Self {
110 match self {
111 RequestObject::Request { jsonrpc, method, params, .. } => {
112 RequestObject::Request { jsonrpc, method, params, id: id.into() }
113 }
114 RequestObject::Notification { jsonrpc, method, params } => {
115 RequestObject::Request { jsonrpc, method, params, id: id.into() }
116 }
117 }
118 }
119
120 pub fn with_method<I: Into<Cow<'static, str>>>(self, method: I) -> Self {
121 match self {
122 RequestObject::Request { jsonrpc, params, id, .. } => {
123 RequestObject::Request { jsonrpc, method: method.into(), params, id }
124 }
125 RequestObject::Notification { jsonrpc, params, .. } => {
126 RequestObject::Notification { jsonrpc, method: method.into(), params }
127 }
128 }
129 }
130
131 pub fn with_params<I: Into<Value>>(self, params: I) -> Self {
132 match self {
133 RequestObject::Request { jsonrpc, method, id, .. } => {
134 RequestObject::Request { jsonrpc, method, params: Some(params.into()), id }
135 }
136 RequestObject::Notification { jsonrpc, method, .. } => {
137 RequestObject::Notification { jsonrpc, method, params: Some(params.into()) }
138 }
139 }
140 }
141
142 pub fn request() -> Self {
143 RequestObject::Request { jsonrpc: V2, method: "".into(), params: None, id: Id::Null }
144 }
145
146 pub fn notification() -> Self {
147 RequestObject::Notification { jsonrpc: V2, method: "".into(), params: None }
148 }
149}
150
151#[derive(Serialize, Deserialize, Default, Debug)]
152pub struct Error {
153 pub code: i64,
154 pub message: String,
155 pub data: Option<Value>
156}
157
158impl Error {
159 pub fn invalid_params() -> Self {
160 Error { code: -32602, message: "Invalid params".into(), data: None }
161 }
162
163 pub fn method_not_found() -> Self {
164 Error { code: -32601, message: "Method not found".into(), data: None }
165 }
166
167 pub fn parse_error() -> Self {
168 Error { code: -32700, message: "Parse error".into(), data: None }
169 }
170
171 pub fn invalid_request() -> Self {
172 Error { code: -32600, message: "Invalid Request".into(), data: None }
173 }
174}
175
176impl<T: std::fmt::Display> From<T> for Error {
177 fn from(t: T) -> Self { Error { message: format!("{}", t), ..Error::default() } }
178}
179
180#[derive(Serialize, Deserialize, Debug)]
181#[serde(untagged)]
182pub enum Response {
183 Result { jsonrpc: V2, result: Value, id: Id },
184 Error { jsonrpc: V2, error: Error, id: Id },
185 Empty
186}
187
188impl Response {
189 fn result(result: Value, opt_id: Option<Id>) -> Self {
190 opt_id
191 .map(|id| Response::Result { jsonrpc: V2, result, id })
192 .unwrap_or_else(|| Response::Empty)
193 }
194
195 fn error(error: Error, opt_id: Option<Id>) -> Self {
196 opt_id
197 .map(|id| Response::Error { jsonrpc: V2, error, id })
198 .unwrap_or_else(|| Response::Empty)
199 }
200}
201
202#[derive(Deserialize)]
203#[serde(untagged)]
204pub enum OneOrManyValues {
205 Many(Vec<Value>),
206 One(Value)
207}
208
209#[derive(Serialize)]
210#[serde(untagged)]
211pub enum ResponseObjects {
212 One(Response),
213 Many(Vec<Response>),
214 None
215}
216
217impl From<Response> for ResponseObjects {
218 fn from(t: Response) -> Self {
219 match t {
220 Response::Empty => ResponseObjects::None,
221 t => ResponseObjects::One(t)
222 }
223 }
224}
225
226impl From<Vec<Response>> for ResponseObjects {
227 fn from(t: Vec<Response>) -> Self {
228 let t = t
229 .into_iter()
230 .filter_map(|r| match r {
231 Response::Empty => None,
232 t => Some(t)
233 })
234 .collect::<Vec<_>>();
235 if t.is_empty() {
236 return ResponseObjects::None;
237 }
238 ResponseObjects::Many(t)
239 }
240}
241
242pub trait Service {
243 fn call(&self, req: RequestObject) -> Box<Future<Item = ResponseObjects, Error = ()> + Send>;
244 fn batch(
245 &self,
246 requests: Vec<RequestObject>
247 ) -> Box<Future<Item = ResponseObjects, Error = ()> + Send>;
248 fn request_from_bytes(
249 &self,
250 bytes: &[u8]
251 ) -> Box<Future<Item = ResponseObjects, Error = ()> + Send>;
252}
253
254type Method<T> = fn(&T, Option<Value>) -> Box<Future<Item = Value, Error = Error> + Send>;
255type MethodMatcher<T> = fn(&str) -> Option<Method<T>>;
256
257pub struct Server<T, S> {
258 state: S,
259 method_matcher: MethodMatcher<T>
260}
261
262impl<T, S> Server<T, S>
263where S: Borrow<T>
264{
265 fn empty_matcher(_: &str) -> Option<Method<T>> { None }
266
267 pub fn new(state: S) -> Self { Server { state, method_matcher: Self::empty_matcher } }
268
269 pub fn with_methods(self, method_matcher: MethodMatcher<T>) -> Self {
270 let Server { state, .. } = self;
271
272 Server { state, method_matcher }
273 }
274
275 fn inner_call(&self, req: RequestObject) -> impl Future<Item = Response, Error = ()> {
276 let (opt_id, method, params) = match req {
277 RequestObject::Notification { method, params, .. } => (None, method, params),
278 RequestObject::Request { method, params, id, .. } => (Some(id), method, params)
279 };
280
281 if let Some(method) = (self.method_matcher)(method.as_ref()) {
282 let rt = method(self.state.borrow(), params).then(|fut| match fut {
283 Ok(val) => future_ok(Response::result(val, opt_id)),
284 Err(e) => future_ok(Response::error(e, opt_id))
285 });
286 EitherFuture::A(rt)
287 } else {
288 let rt = future_ok(Response::error(Error::method_not_found(), opt_id));
289 EitherFuture::B(rt)
290 }
291 }
292
293 fn inner_batch(
294 &self,
295 requests: Vec<RequestObject>
296 ) -> impl Future<Item = Vec<Response>, Error = ()>
297 {
298 use futures::stream::Stream;
299 futures::stream::futures_unordered(requests.into_iter().map(|r| self.inner_call(r)))
300 .collect()
301 }
302}
303
304impl<T: 'static, S: 'static> Service for Server<T, S>
305where S: Borrow<T>
306{
307 fn call(&self, req: RequestObject) -> Box<Future<Item = ResponseObjects, Error = ()> + Send> {
308 Box::new(self.inner_call(req).map(ResponseObjects::from))
309 }
310
311 fn batch(
312 &self,
313 requests: Vec<RequestObject>
314 ) -> Box<Future<Item = ResponseObjects, Error = ()> + Send>
315 {
316 Box::new(self.inner_batch(requests).map(ResponseObjects::from))
317 }
318
319 fn request_from_bytes(
320 &self,
321 bytes: &[u8]
322 ) -> Box<Future<Item = ResponseObjects, Error = ()> + Send>
323 {
324 if let Ok(mr) = serde_json::from_slice::<OneOrManyValues>(bytes) {
325 match mr {
326 OneOrManyValues::One(val) => {
327 return Box::new(match serde_json::from_value::<RequestObject>(val) {
328 Ok(rn) => EitherFuture::A(self.call(rn)),
329 Err(_) => EitherFuture::B(future_ok(
330 Response::error(Error::invalid_request(), Some(Id::Null)).into()
331 ))
332 });
333 }
334 OneOrManyValues::Many(vals) => {
335 if vals.is_empty() {
336 return Box::new(future_ok(
337 Response::error(Error::invalid_request(), Some(Id::Null)).into()
338 ));
339 }
340
341 let (okays, errs) = vals
342 .into_iter()
343 .map(serde_json::from_value::<RequestObject>)
344 .partition::<Vec<Result<RequestObject, serde_json::Error>>, _>(|x| {
345 x.is_ok()
346 });
347
348 let errs = errs
349 .into_iter()
350 .map(|_| Response::error(Error::invalid_request(), Some(Id::Null)))
351 .collect::<Vec<_>>();
352
353 return Box::new(
354 self.inner_batch(okays.into_iter().flat_map(|x| x).collect()).map(
355 |mut rs| {
356 rs.extend(errs);
357 rs.into()
358 }
359 )
360 );
361 }
362 }
363 }
364
365 Box::new(future_ok(Response::error(Error::parse_error(), Some(Id::Null)).into()))
366 }
367}
368
369pub mod utils {
370
371 use super::Error;
372 use futures::{Future, IntoFuture};
373
374 pub fn finish_callable<I, S, E>(
375 i: I
376 ) -> Box<Future<Item = serde_json::Value, Error = Error> + Send>
377 where
378 I: IntoFuture<Item = S, Error = E> + 'static + Send,
379 I::Future: 'static + Send,
380 S: serde::Serialize,
381 E: Into<Error> {
382 let rt = i.into_future().map_err(|e| e.into()).and_then(|r| {
383 serde_json::to_value(r).into_future().map_err(|e| Error {
384 code: 1,
385 message: e.to_string(),
386 data: None
387 })
388 });
389 Box::new(rt)
390 }
391}
392
393pub mod exp {
394 pub use futures;
395 pub use serde;
396 pub use serde_json;
397}