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