1#![allow(non_snake_case)]
4
5use rs_jsonrpc_core::{Error, Params, Value, Metadata, Result};
8use rs_jsonrpc_core::futures::{self, Future, IntoFuture};
9use rs_jsonrpc_core::futures::future::{self, Either};
10use rs_jsonrpc_pubsub::{PubSubMetadata, Subscriber};
11use pubsub;
12use serde::Serialize;
13use serde::de::DeserializeOwned;
14use util::{invalid_params, expect_no_params, to_value};
15
16#[macro_export]
60macro_rules! metadata {
61 () => {
62 type Metadata: $crate::rs_jsonrpc_core::Metadata;
64 };
65 (
66 $( $sub_name: ident )+
67 ) => {
68 type Metadata: $crate::rs_jsonrpc_pubsub::PubSubMetadata;
70 };
71}
72
73#[macro_export]
74macro_rules! build_rpc_trait {
75 (
77 $(#[$t_attr: meta])*
78 pub trait $name: ident {
79 $(
80 $( #[doc=$m_doc:expr] )*
81 #[ rpc( $($t:tt)* ) ]
82 fn $m_name: ident ( $($p: tt)* ) -> $result: tt <$out: ty $(, $error: ty)* >;
83 )*
84 }
85 ) => {
86 $(#[$t_attr])*
87 pub trait $name: Sized + Send + Sync + 'static {
88 $(
89 $(#[doc=$m_doc])*
90 fn $m_name ( $($p)* ) -> $result<$out $(, $error)* > ;
91 )*
92
93 fn to_delegate<M: $crate::rs_jsonrpc_core::Metadata>(self) -> $crate::IoDelegate<Self, M> {
96 let mut del = $crate::IoDelegate::new(self.into());
97 $(
98 build_rpc_trait!(WRAP del =>
99 ( $($t)* )
100 fn $m_name ( $($p)* ) -> $result <$out $(, $error)* >
101 );
102 )*
103 del
104 }
105 }
106 };
107
108 (
110 $(#[$t_attr: meta])*
111 pub trait $name: ident {
112 type Metadata;
113
114 $(
115 $( #[ doc=$m_doc:expr ] )*
116 #[ rpc( $($t:tt)* ) ]
117 fn $m_name: ident ( $($p: tt)* ) -> $result: tt <$out: ty $(, $error_std: ty) *>;
118 )*
119
120 $(
121 #[ pubsub( $($pubsub_t:tt)+ ) ] {
122 $( #[ doc= $sub_doc:expr ] )*
123 #[ rpc( $($sub_t:tt)* ) ]
124 fn $sub_name: ident ( $($sub_p: tt)* );
125 $( #[ doc= $unsub_doc:expr ] )*
126 #[ rpc( $($unsub_t:tt)* ) ]
127 fn $unsub_name: ident ( $($unsub_p: tt)* ) -> $sub_result: tt <$sub_out: ty $(, $error_unsub: ty)* >;
128 }
129 )*
130
131 }
132 ) => {
133 $(#[$t_attr])*
134 pub trait $name: Sized + Send + Sync + 'static {
135 metadata! (
137 $( $sub_name )*
138 );
139
140 $(
141 $(#[doc=$m_doc])*
142 fn $m_name ( $($p)* ) -> $result <$out $(, $error_std) *>;
143 )*
144
145 $(
146 $(#[doc=$sub_doc])*
147 fn $sub_name ( $($sub_p)* );
148 $(#[doc=$unsub_doc])*
149 fn $unsub_name ( $($unsub_p)* ) -> $sub_result <$sub_out $(, $error_unsub)* >;
150 )*
151
152 fn to_delegate(self) -> $crate::IoDelegate<Self, Self::Metadata> {
155 let mut del = $crate::IoDelegate::new(self.into());
156 $(
157 build_rpc_trait!(WRAP del =>
158 ( $($t)* )
159 fn $m_name ( $($p)* ) -> $result <$out $(, $error_std)* >
160 );
161 )*
162 $(
163 build_rpc_trait!(WRAP del =>
164 pubsub: ( $($pubsub_t)* )
165 subscribe: ( $($sub_t)* )
166 fn $sub_name ( $($sub_p)* );
167 unsubscribe: ( $($unsub_t)* )
168 fn $unsub_name ( $($unsub_p)* ) -> $sub_result <$sub_out $(, $error_unsub)* >;
169 );
170 )*
171 del
172 }
173 }
174 };
175
176 ( WRAP $del: expr =>
177 (name = $name: expr $(, alias = [ $( $alias: expr, )+ ])*)
178 fn $method: ident (&self $(, $param: ty)*) -> $result: tt <$out: ty $(, $error: ty)* >
179 ) => {
180 $del.add_method($name, move |base, params| {
181 $crate::WrapAsync::wrap_rpc(&(Self::$method as fn(&_ $(, $param)*) -> $result <$out $(, $error)*>), base, params)
182 });
183 $(
184 $(
185 $del.add_alias($alias, $name);
186 )+
187 )*
188 };
189
190 ( WRAP $del: expr =>
191 (meta, name = $name: expr $(, alias = [ $( $alias: expr, )+ ])*)
192 fn $method: ident (&self, Self::Metadata $(, $param: ty)*) -> $result: tt <$out: ty $(, $error: ty)* >
193 ) => {
194 $del.add_method_with_meta($name, move |base, params, meta| {
195 $crate::WrapMeta::wrap_rpc(&(Self::$method as fn(&_, Self::Metadata $(, $param)*) -> $result <$out $(, $error)* >), base, params, meta)
196 });
197 $(
198 $(
199 $del.add_alias($alias, $name);
200 )+
201 )*
202 };
203
204 ( WRAP $del: expr =>
205 pubsub: (name = $name: expr)
206 subscribe: (name = $subscribe: expr $(, alias = [ $( $sub_alias: expr, )+ ])*)
207 fn $sub_method: ident (&self, Self::Metadata $(, $sub_p: ty)+);
208 unsubscribe: (name = $unsubscribe: expr $(, alias = [ $( $unsub_alias: expr, )+ ])*)
209 fn $unsub_method: ident (&self $(, $unsub_p: ty)+) -> $result: tt <$out: ty $(, $error_unsub: ty)* >;
210 ) => {
211 $del.add_subscription(
212 $name,
213 ($subscribe, move |base, params, meta, subscriber| {
214 $crate::WrapSubscribe::wrap_rpc(
215 &(Self::$sub_method as fn(&_, Self::Metadata $(, $sub_p)*)),
216 base,
217 params,
218 meta,
219 subscriber,
220 )
221 }),
222 ($unsubscribe, move |base, id| {
223 use $crate::rs_jsonrpc_core::futures::{IntoFuture, Future};
224 Self::$unsub_method(base, id).into_future().map($crate::to_value)
225 }),
226 );
227
228 $(
229 $(
230 $del.add_alias($sub_alias, $subscribe);
231 )*
232 )*
233 $(
234 $(
235 $del.add_alias($unsub_alias, $unsubscribe);
236 )*
237 )*
238 };
239}
240
241pub struct Trailing<T>(Option<T>);
245
246impl<T> Into<Option<T>> for Trailing<T> {
247 fn into(self) -> Option<T> {
248 self.0
249 }
250}
251
252impl<T: DeserializeOwned> Trailing<T> {
253 pub fn unwrap_or(self, other: T) -> T {
255 self.0.unwrap_or(other)
256 }
257
258 pub fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
260 self.0.unwrap_or_else(f)
261 }
262}
263
264impl<T: Default + DeserializeOwned> Trailing<T> {
265 pub fn unwrap_or_default(self) -> T {
267 self.0.unwrap_or_default()
268 }
269}
270
271type WrappedFuture<F, OUT, E> = future::MapErr<
272 future::Map<F, fn(OUT) -> Value>,
273 fn(E) -> Error
274>;
275type WrapResult<F, OUT, E> = Either<
276 WrappedFuture<F, OUT, E>,
277 future::FutureResult<Value, Error>,
278>;
279
280fn as_future<F, OUT, E, I>(el: I) -> WrappedFuture<F, OUT, E> where
281 OUT: Serialize,
282 E: Into<Error>,
283 F: Future<Item = OUT, Error = E>,
284 I: IntoFuture<Item = OUT, Error = E, Future = F>
285{
286 el.into_future()
287 .map(to_value as fn(OUT) -> Value)
288 .map_err(Into::into as fn(E) -> Error)
289}
290
291pub trait WrapAsync<B> {
293 type Out: IntoFuture<Item = Value, Error = Error>;
295
296 fn wrap_rpc(&self, base: &B, params: Params) -> Self::Out;
298}
299
300pub trait WrapMeta<B, M> {
302 type Out: IntoFuture<Item = Value, Error = Error>;
304 fn wrap_rpc(&self, base: &B, params: Params, meta: M) -> Self::Out;
306}
307
308pub trait WrapSubscribe<B, M> {
310 fn wrap_rpc(&self, base: &B, params: Params, meta: M, subscriber: Subscriber);
312}
313
314impl<B, OUT, E, F, I> WrapAsync<B> for fn(&B) -> I where
316 B: Send + Sync + 'static,
317 OUT: Serialize + 'static,
318 E: Into<Error> + 'static,
319 F: Future<Item = OUT, Error = E> + Send + 'static,
320 I: IntoFuture<Item = OUT, Error = E, Future = F>,
321{
322 type Out = WrapResult<F, OUT, E>;
323
324 fn wrap_rpc(&self, base: &B, params: Params) -> Self::Out {
325 match expect_no_params(params) {
326 Ok(()) => Either::A(as_future((self)(base))),
327 Err(e) => Either::B(futures::failed(e)),
328 }
329 }
330}
331
332impl<M, B, OUT, E, F, I> WrapMeta<B, M> for fn(&B, M) -> I where
333 M: Metadata,
334 B: Send + Sync + 'static,
335 OUT: Serialize + 'static,
336 E: Into<Error> + 'static,
337 F: Future<Item = OUT, Error = E> + Send + 'static,
338 I: IntoFuture<Item = OUT, Error = E, Future = F>,
339{
340 type Out = WrapResult<F, OUT, E>;
341
342 fn wrap_rpc(&self, base: &B, params: Params, meta: M) -> Self::Out {
343 match expect_no_params(params) {
344 Ok(()) => Either::A(as_future((self)(base, meta))),
345 Err(e) => Either::B(futures::failed(e)),
346 }
347 }
348}
349
350impl<M, B, OUT> WrapSubscribe<B, M> for fn(&B, M, pubsub::Subscriber<OUT>) where
351 M: PubSubMetadata,
352 B: Send + Sync + 'static,
353 OUT: Serialize,
354{
355 fn wrap_rpc(&self, base: &B, params: Params, meta: M, subscriber: Subscriber) {
356 match expect_no_params(params) {
357 Ok(()) => (self)(base, meta, pubsub::Subscriber::new(subscriber)),
358 Err(e) => {
359 let _ = subscriber.reject(e);
360 },
361 }
362 }
363}
364
365macro_rules! wrap {
368 ($($x: ident),+) => {
369
370 impl <
372 BASE: Send + Sync + 'static,
373 OUT: Serialize + 'static,
374 $($x: DeserializeOwned,)+
375 ERR: Into<Error> + 'static,
376 X: Future<Item = OUT, Error = ERR> + Send + 'static,
377 Z: IntoFuture<Item = OUT, Error = ERR, Future = X>,
378 > WrapAsync<BASE> for fn(&BASE, $($x,)+ ) -> Z {
379 type Out = WrapResult<X, OUT, ERR>;
380 fn wrap_rpc(&self, base: &BASE, params: Params) -> Self::Out {
381 match params.parse::<($($x,)+)>() {
382 Ok(($($x,)+)) => Either::A(as_future((self)(base, $($x,)+))),
383 Err(e) => Either::B(futures::failed(e)),
384 }
385 }
386 }
387
388 impl <
390 BASE: Send + Sync + 'static,
391 META: Metadata,
392 OUT: Serialize + 'static,
393 $($x: DeserializeOwned,)+
394 ERR: Into<Error> + 'static,
395 X: Future<Item = OUT, Error = ERR> + Send + 'static,
396 Z: IntoFuture<Item = OUT, Error = ERR, Future = X>,
397 > WrapMeta<BASE, META> for fn(&BASE, META, $($x,)+) -> Z {
398 type Out = WrapResult<X, OUT, ERR>;
399 fn wrap_rpc(&self, base: &BASE, params: Params, meta: META) -> Self::Out {
400 match params.parse::<($($x,)+)>() {
401 Ok(($($x,)+)) => Either::A(as_future((self)(base, meta, $($x,)+))),
402 Err(e) => Either::B(futures::failed(e)),
403 }
404 }
405 }
406
407 impl <
409 BASE: Send + Sync + 'static,
410 META: PubSubMetadata,
411 OUT: Serialize,
412 $($x: DeserializeOwned,)+
413 > WrapSubscribe<BASE, META> for fn(&BASE, META, pubsub::Subscriber<OUT>, $($x,)+) {
414 fn wrap_rpc(&self, base: &BASE, params: Params, meta: META, subscriber: Subscriber) {
415 match params.parse::<($($x,)+)>() {
416 Ok(($($x,)+)) => (self)(base, meta, pubsub::Subscriber::new(subscriber), $($x,)+),
417 Err(e) => {
418 let _ = subscriber.reject(e);
419 },
420 }
421 }
422 }
423 }
424}
425
426fn params_len(params: &Params) -> Result<usize> {
427 match *params {
428 Params::Array(ref v) => Ok(v.len()),
429 Params::None => Ok(0),
430 _ => Err(invalid_params("`params` should be an array", "")),
431 }
432}
433
434fn require_len(params: &Params, required: usize) -> Result<usize> {
435 let len = params_len(params)?;
436 if len < required {
437 return Err(invalid_params(&format!("`params` should have at least {} argument(s)", required), ""));
438 }
439 Ok(len)
440}
441
442fn parse_trailing_param<T: DeserializeOwned>(params: Params) -> Result<(Option<T>, )> {
443 let len = try!(params_len(¶ms));
444 let id = match len {
445 0 => Ok((None,)),
446 1 => params.parse::<(T,)>().map(|(x, )| (Some(x), )),
447 _ => Err(invalid_params("Expecting only one optional parameter.", "")),
448 };
449
450 id
451}
452
453impl<B, OUT, T, E, F, I> WrapAsync<B> for fn(&B, Trailing<T>) -> I where
455 B: Send + Sync + 'static,
456 OUT: Serialize + 'static,
457 T: DeserializeOwned,
458 E: Into<Error> + 'static,
459 F: Future<Item = OUT, Error = E> + Send + 'static,
460 I: IntoFuture<Item = OUT, Error = E, Future = F>,
461{
462 type Out = WrapResult<F, OUT, E>;
463 fn wrap_rpc(&self, base: &B, params: Params) -> Self::Out {
464 let id = parse_trailing_param(params);
465
466 match id {
467 Ok((id,)) => Either::A(as_future((self)(base, Trailing(id)))),
468 Err(e) => Either::B(futures::failed(e)),
469 }
470 }
471}
472
473impl<M, B, OUT, T, E, F, I> WrapMeta<B, M> for fn(&B, M, Trailing<T>) -> I where
474 M: Metadata,
475 B: Send + Sync + 'static,
476 OUT: Serialize + 'static,
477 T: DeserializeOwned,
478 E: Into<Error> + 'static,
479 F: Future<Item = OUT, Error = E> + Send + 'static,
480 I: IntoFuture<Item = OUT, Error = E, Future = F>,
481{
482 type Out = WrapResult<F, OUT, E>;
483 fn wrap_rpc(&self, base: &B, params: Params, meta: M) -> Self::Out {
484 let id = parse_trailing_param(params);
485
486 match id {
487 Ok((id,)) => Either::A(as_future((self)(base, meta, Trailing(id)))),
488 Err(e) => Either::B(futures::failed(e)),
489 }
490 }
491}
492
493impl<M, B, OUT, T> WrapSubscribe<B, M> for fn(&B, M, pubsub::Subscriber<OUT>, Trailing<T>) where
494 M: PubSubMetadata,
495 B: Send + Sync + 'static,
496 OUT: Serialize,
497 T: DeserializeOwned,
498{
499 fn wrap_rpc(&self, base: &B, params: Params, meta: M, subscriber: Subscriber) {
500 let id = parse_trailing_param(params);
501
502 match id {
503 Ok((id,)) => (self)(base, meta, pubsub::Subscriber::new(subscriber), Trailing(id)),
504 Err(e) => {
505 let _ = subscriber.reject(e);
506 },
507 }
508 }
509}
510
511macro_rules! wrap_with_trailing {
514 ($num: expr, $($x: ident),+) => {
515 impl <
517 BASE: Send + Sync + 'static,
518 OUT: Serialize + 'static,
519 $($x: DeserializeOwned,)+
520 TRAILING: DeserializeOwned,
521 ERR: Into<Error> + 'static,
522 X: Future<Item = OUT, Error = ERR> + Send + 'static,
523 Z: IntoFuture<Item = OUT, Error = ERR, Future = X>,
524 > WrapAsync<BASE> for fn(&BASE, $($x,)+ Trailing<TRAILING>) -> Z {
525 type Out = WrapResult<X, OUT, ERR>;
526 fn wrap_rpc(&self, base: &BASE, params: Params) -> Self::Out {
527 let len = match require_len(¶ms, $num) {
528 Ok(len) => len,
529 Err(e) => return Either::B(futures::failed(e)),
530 };
531
532 let params = match len - $num {
533 0 => params.parse::<($($x,)+)>()
534 .map(|($($x,)+)| ($($x,)+ None)).map_err(Into::into),
535 1 => params.parse::<($($x,)+ TRAILING)>()
536 .map(|($($x,)+ id)| ($($x,)+ Some(id))).map_err(Into::into),
537 _ => Err(invalid_params(&format!("Expected {} or {} parameters.", $num, $num + 1), format!("Got: {}", len))),
538 };
539
540 match params {
541 Ok(($($x,)+ id)) => Either::A(as_future((self)(base, $($x,)+ Trailing(id)))),
542 Err(e) => Either::B(futures::failed(e)),
543 }
544 }
545 }
546
547 impl <
549 BASE: Send + Sync + 'static,
550 META: Metadata,
551 OUT: Serialize + 'static,
552 $($x: DeserializeOwned,)+
553 TRAILING: DeserializeOwned,
554 ERR: Into<Error> + 'static,
555 X: Future<Item = OUT, Error = ERR> + Send + 'static,
556 Z: IntoFuture<Item = OUT, Error = ERR, Future = X>,
557 > WrapMeta<BASE, META> for fn(&BASE, META, $($x,)+ Trailing<TRAILING>) -> Z {
558 type Out = WrapResult<X, OUT, ERR>;
559 fn wrap_rpc(&self, base: &BASE, params: Params, meta: META) -> Self::Out {
560 let len = match require_len(¶ms, $num) {
561 Ok(len) => len,
562 Err(e) => return Either::B(futures::failed(e)),
563 };
564
565 let params = match len - $num {
566 0 => params.parse::<($($x,)+)>()
567 .map(|($($x,)+)| ($($x,)+ None)).map_err(Into::into),
568 1 => params.parse::<($($x,)+ TRAILING)>()
569 .map(|($($x,)+ id)| ($($x,)+ Some(id))).map_err(Into::into),
570 _ => Err(invalid_params(&format!("Expected {} or {} parameters.", $num, $num + 1), format!("Got: {}", len))),
571 };
572
573 match params {
574 Ok(($($x,)+ id)) => Either::A(as_future((self)(base, meta, $($x,)+ Trailing(id)))),
575 Err(e) => Either::B(futures::failed(e)),
576 }
577 }
578 }
579
580 impl <
582 BASE: Send + Sync + 'static,
583 META: PubSubMetadata,
584 OUT: Serialize,
585 $($x: DeserializeOwned,)+
586 TRAILING: DeserializeOwned,
587 > WrapSubscribe<BASE, META> for fn(&BASE, META, pubsub::Subscriber<OUT>, $($x,)+ Trailing<TRAILING>) {
588 fn wrap_rpc(&self, base: &BASE, params: Params, meta: META, subscriber: Subscriber) {
589 let len = match require_len(¶ms, $num) {
590 Ok(len) => len,
591 Err(e) => {
592 let _ = subscriber.reject(e);
593 return;
594 },
595 };
596
597 let params = match len - $num {
598 0 => params.parse::<($($x,)+)>()
599 .map(|($($x,)+)| ($($x,)+ None)),
600 1 => params.parse::<($($x,)+ TRAILING)>()
601 .map(|($($x,)+ id)| ($($x,)+ Some(id))),
602 _ => {
603 let _ = subscriber.reject(invalid_params(&format!("Expected {} or {} parameters.", $num, $num + 1), format!("Got: {}", len)));
604 return;
605 },
606 };
607
608 match params {
609 Ok(($($x,)+ id)) => (self)(base, meta, pubsub::Subscriber::new(subscriber), $($x,)+ Trailing(id)),
610 Err(e) => {
611 let _ = subscriber.reject(e);
612 return;
613 },
614 }
615 }
616 }
617 }
618}
619
620wrap!(A, B, C, D, E, F);
621wrap!(A, B, C, D, E);
622wrap!(A, B, C, D);
623wrap!(A, B, C);
624wrap!(A, B);
625wrap!(A);
626
627wrap_with_trailing!(6, A, B, C, D, E, F);
628wrap_with_trailing!(5, A, B, C, D, E);
629wrap_with_trailing!(4, A, B, C, D);
630wrap_with_trailing!(3, A, B, C);
631wrap_with_trailing!(2, A, B);
632wrap_with_trailing!(1, A);
633