1#![allow(non_snake_case)]
4
5use jsonrpc_core::{Error, Params, Value, Metadata};
8use jsonrpc_core::futures::{self, BoxFuture, Future};
9use jsonrpc_pubsub::{PubSubMetadata, Subscriber};
10use pubsub;
11use serde::Serialize;
12use serde::de::DeserializeOwned;
13use util::{invalid_params, expect_no_params, to_value};
14
15#[macro_export]
60macro_rules! metadata {
61 () => {
62 type Metadata: ::jsonrpc_core::Metadata;
64 };
65 (
66 $( $sub_name: ident )+
67 ) => {
68 type Metadata: ::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: ::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::Wrap::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 (async, name = $name: expr $(, alias = [ $( $alias: expr, )+ ])*)
192 fn $method: ident (&self $(, $param: ty)*) -> $result: tt <$out: ty, $error: ty>
193 ) => {
194 $del.add_async_method($name, move |base, params| {
195 $crate::WrapAsync::wrap_rpc(&(Self::$method as fn(&_ $(, $param)*) -> $result <$out, $error>), base, params)
196 });
197 $(
198 $(
199 $del.add_alias($alias, $name);
200 )+
201 )*
202 };
203
204 ( WRAP $del: expr =>
205 (meta, name = $name: expr $(, alias = [ $( $alias: expr, )+ ])*)
206 fn $method: ident (&self, Self::Metadata $(, $param: ty)*) -> $result: tt <$out: ty, $error: ty>
207 ) => {
208 $del.add_method_with_meta($name, move |base, params, meta| {
209 $crate::WrapMeta::wrap_rpc(&(Self::$method as fn(&_, Self::Metadata $(, $param)*) -> $result <$out, Error>), base, params, meta)
210 });
211 $(
212 $(
213 $del.add_alias($alias, $name);
214 )+
215 )*
216 };
217
218 ( WRAP $del: expr =>
219 pubsub: (name = $name: expr)
220 subscribe: (name = $subscribe: expr $(, alias = [ $( $sub_alias: expr, )+ ])*)
221 fn $sub_method: ident (&self, Self::Metadata $(, $sub_p: ty)+);
222 unsubscribe: (name = $unsubscribe: expr $(, alias = [ $( $unsub_alias: expr, )+ ])*)
223 fn $unsub_method: ident (&self $(, $unsub_p: ty)+) -> $result: tt <$out: ty, $error_unsub: ty>;
224 ) => {
225 $del.add_subscription(
226 $name,
227 ($subscribe, move |base, params, meta, subscriber| {
228 $crate::WrapSubscribe::wrap_rpc(
229 &(Self::$sub_method as fn(&_, Self::Metadata $(, $sub_p)*)),
230 base,
231 params,
232 meta,
233 subscriber,
234 )
235 }),
236 ($unsubscribe, move |base, id| {
237 use $crate::jsonrpc_core::futures::Future;
238 Self::$unsub_method(base, id).map($crate::to_value).boxed()
239 }),
240 );
241
242 $(
243 $(
244 $del.add_alias($sub_alias, $subscribe);
245 )*
246 )*
247 $(
248 $(
249 $del.add_alias($unsub_alias, $unsubscribe);
250 )*
251 )*
252 };
253}
254
255pub struct Trailing<T>(Option<T>);
259
260impl<T> Into<Option<T>> for Trailing<T> {
261 fn into(self) -> Option<T> {
262 self.0
263 }
264}
265
266impl<T: DeserializeOwned> Trailing<T> {
267 pub fn unwrap_or(self, other: T) -> T {
269 self.0.unwrap_or(other)
270 }
271
272 pub fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
274 self.0.unwrap_or_else(f)
275 }
276}
277
278impl<T: Default + DeserializeOwned> Trailing<T> {
279 pub fn unwrap_or_default(self) -> T {
281 self.0.unwrap_or_default()
282 }
283}
284
285pub trait Wrap<B> {
287 fn wrap_rpc(&self, base: &B, params: Params) -> Result<Value, Error>;
289}
290
291pub trait WrapAsync<B> {
293 fn wrap_rpc(&self, base: &B, params: Params) -> BoxFuture<Value, Error>;
295}
296
297pub trait WrapMeta<B, M> {
299 fn wrap_rpc(&self, base: &B, params: Params, meta: M) -> BoxFuture<Value, Error>;
301}
302
303pub trait WrapSubscribe<B, M> {
305 fn wrap_rpc(&self, base: &B, params: Params, meta: M, subscriber: Subscriber);
307}
308
309impl<B, OUT, E> Wrap<B> for fn(&B) -> Result<OUT, E>
311 where B: Send + Sync + 'static, OUT: Serialize + 'static, E: Into<Error> + 'static
312{
313 fn wrap_rpc(&self, base: &B, params: Params) -> Result<Value, Error> {
314 match expect_no_params(params) {
315 Ok(()) => (self)(base).map(to_value).map_err(Into::into),
316 Err(e) => Err(e),
317 }
318 }
319}
320
321impl<B, OUT, E> WrapAsync<B> for fn(&B) -> BoxFuture<OUT, E>
322 where B: Send + Sync + 'static, OUT: Serialize + 'static, E: Into<Error> + 'static
323{
324 fn wrap_rpc(&self, base: &B, params: Params) -> BoxFuture<Value, Error> {
325 match expect_no_params(params) {
326 Ok(()) => (self)(base).map(to_value).map_err(Into::into).boxed(),
327 Err(e) => futures::failed(e).boxed(),
328 }
329 }
330}
331
332impl<B, M, OUT, E> WrapMeta<B, M> for fn(&B, M) -> BoxFuture<OUT, E>
333 where B: Send + Sync + 'static, OUT: Serialize + 'static, M: Metadata, E: Into<Error> + 'static
334{
335 fn wrap_rpc(&self, base: &B, params: Params, meta: M) -> BoxFuture<Value, Error> {
336 match expect_no_params(params) {
337 Ok(()) => (self)(base, meta).map(to_value).map_err(Into::into).boxed(),
338 Err(e) => futures::failed(e.into()).boxed(),
339 }
340 }
341}
342
343impl<B, M, OUT> WrapSubscribe<B, M> for fn(&B, M, pubsub::Subscriber<OUT>)
344 where B: Send + Sync + 'static, OUT: Serialize, M: PubSubMetadata
345{
346 fn wrap_rpc(&self, base: &B, params: Params, meta: M, subscriber: Subscriber) {
347 match expect_no_params(params) {
348 Ok(()) => (self)(base, meta, pubsub::Subscriber::new(subscriber)),
349 Err(e) => {
350 let _ = subscriber.reject(e);
351 },
352 }
353 }
354}
355
356macro_rules! wrap {
359 ($($x: ident),+) => {
360
361 impl <
363 BASE: Send + Sync + 'static,
364 OUT: Serialize + 'static,
365 $($x: DeserializeOwned,)+
366 ERR: Into<Error> + 'static,
367 > Wrap<BASE> for fn(&BASE, $($x,)+) -> Result<OUT, ERR> {
368 fn wrap_rpc(&self, base: &BASE, params: Params) -> Result<Value, Error> {
369 match params.parse::<($($x,)+)>() {
370 Ok(($($x,)+)) => (self)(base, $($x,)+).map(to_value).map_err(Into::into),
371 Err(e) => Err(e)
372 }
373 }
374 }
375
376 impl <
378 BASE: Send + Sync + 'static,
379 OUT: Serialize + 'static,
380 $($x: DeserializeOwned,)+
381 ERR: Into<Error> + 'static
382 > WrapAsync<BASE> for fn(&BASE, $($x,)+ ) -> BoxFuture<OUT, ERR> {
383 fn wrap_rpc(&self, base: &BASE, params: Params) -> BoxFuture<Value, Error> {
384 match params.parse::<($($x,)+)>() {
385 Ok(($($x,)+)) => (self)(base, $($x,)+).map(to_value).map_err(Into::into).boxed(),
386 Err(e) => futures::failed(e).boxed(),
387 }
388 }
389 }
390
391 impl <
393 BASE: Send + Sync + 'static,
394 META: Metadata,
395 OUT: Serialize + 'static,
396 $($x: DeserializeOwned,)+
397 ERR: Into<Error> + 'static
398 > WrapMeta<BASE, META> for fn(&BASE, META, $($x,)+) -> BoxFuture<OUT, ERR> {
399 fn wrap_rpc(&self, base: &BASE, params: Params, meta: META) -> BoxFuture<Value, Error> {
400 match params.parse::<($($x,)+)>() {
401 Ok(($($x,)+)) => (self)(base, meta, $($x,)+).map(to_value).map_err(Into::into).boxed(),
402 Err(e) => futures::failed(e).boxed(),
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, Error> {
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, Error> {
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>, ), Error> {
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> Wrap<B> for fn(&B, Trailing<T>) -> Result<OUT, E>
455 where B: Send + Sync + 'static, OUT: Serialize + 'static, T: DeserializeOwned, E: Into<Error> + 'static
456{
457 fn wrap_rpc(&self, base: &B, params: Params) -> Result<Value, Error> {
458 let id = try!(parse_trailing_param(params)).0;
459
460 (self)(base, Trailing(id)).map(to_value).map_err(Into::into)
461 }
462}
463
464impl<B, OUT, T, E> WrapAsync<B> for fn(&B, Trailing<T>) -> BoxFuture<OUT, E>
465 where B: Send + Sync + 'static, OUT: Serialize + 'static, T: DeserializeOwned, E: Into<Error> + 'static
466{
467 fn wrap_rpc(&self, base: &B, params: Params) -> BoxFuture<Value, Error> {
468 let id = parse_trailing_param(params);
469
470 match id {
471 Ok((id,)) => (self)(base, Trailing(id)).map(to_value).map_err(Into::into).boxed(),
472 Err(e) => futures::failed(e).boxed(),
473 }
474 }
475}
476
477impl<B, M, OUT, T, E> WrapMeta<B, M> for fn(&B, M, Trailing<T>) -> BoxFuture<OUT, E>
478 where B: Send + Sync + 'static, OUT: Serialize + 'static, T: DeserializeOwned, M: Metadata, E: Into<Error> + 'static
479{
480 fn wrap_rpc(&self, base: &B, params: Params, meta: M) -> BoxFuture<Value, Error> {
481 let id = parse_trailing_param(params);
482
483 match id {
484 Ok((id,)) => (self)(base, meta, Trailing(id)).map(to_value).map_err(Into::into).boxed(),
485 Err(e) => futures::failed(e).boxed(),
486 }
487 }
488}
489
490impl<B, M, OUT, T> WrapSubscribe<B, M> for fn(&B, M, pubsub::Subscriber<OUT>, Trailing<T>)
491 where B: Send + Sync + 'static, OUT: Serialize, M: PubSubMetadata, T: DeserializeOwned,
492{
493 fn wrap_rpc(&self, base: &B, params: Params, meta: M, subscriber: Subscriber) {
494 let id = parse_trailing_param(params);
495
496 match id {
497 Ok((id,)) => (self)(base, meta, pubsub::Subscriber::new(subscriber), Trailing(id)),
498 Err(e) => {
499 let _ = subscriber.reject(e);
500 },
501 }
502 }
503}
504
505macro_rules! wrap_with_trailing {
508 ($num: expr, $($x: ident),+) => {
509 impl <
511 BASE: Send + Sync + 'static,
512 OUT: Serialize + 'static,
513 $($x: DeserializeOwned,)+
514 TRAILING: DeserializeOwned,
515 ERR: Into<Error> + 'static
516 > Wrap<BASE> for fn(&BASE, $($x,)+ Trailing<TRAILING>) -> Result<OUT, ERR> {
517 fn wrap_rpc(&self, base: &BASE, params: Params) -> Result<Value, Error> {
518 let len = require_len(¶ms, $num)?;
519
520 let params = match len - $num {
521 0 => params.parse::<($($x,)+)>()
522 .map(|($($x,)+)| ($($x,)+ None)).map_err(Into::into),
523 1 => params.parse::<($($x,)+ TRAILING)>()
524 .map(|($($x,)+ id)| ($($x,)+ Some(id))).map_err(Into::into),
525 _ => Err(invalid_params(&format!("Expected {} or {} parameters.", $num, $num + 1), format!("Got: {}", len))),
526 };
527
528 let ($($x,)+ id) = try!(params);
529 (self)(base, $($x,)+ Trailing(id)).map(to_value).map_err(Into::into)
530 }
531 }
532
533 impl <
535 BASE: Send + Sync + 'static,
536 OUT: Serialize + 'static,
537 $($x: DeserializeOwned,)+
538 TRAILING: DeserializeOwned,
539 ERR: Into<Error> + 'static
540 > WrapAsync<BASE> for fn(&BASE, $($x,)+ Trailing<TRAILING>) -> BoxFuture<OUT, ERR> {
541 fn wrap_rpc(&self, base: &BASE, params: Params) -> BoxFuture<Value, Error> {
542 let len = match require_len(¶ms, $num) {
543 Ok(len) => len,
544 Err(e) => return futures::failed(e).boxed(),
545 };
546
547 let params = match len - $num {
548 0 => params.parse::<($($x,)+)>()
549 .map(|($($x,)+)| ($($x,)+ None)).map_err(Into::into),
550 1 => params.parse::<($($x,)+ TRAILING)>()
551 .map(|($($x,)+ id)| ($($x,)+ Some(id))).map_err(Into::into),
552 _ => Err(invalid_params(&format!("Expected {} or {} parameters.", $num, $num + 1), format!("Got: {}", len))),
553 };
554
555 match params {
556 Ok(($($x,)+ id)) => (self)(base, $($x,)+ Trailing(id)).map(to_value).map_err(Into::into).boxed(),
557 Err(e) => futures::failed(e).boxed(),
558 }
559 }
560 }
561
562 impl <
564 BASE: Send + Sync + 'static,
565 META: Metadata,
566 OUT: Serialize + 'static,
567 $($x: DeserializeOwned,)+
568 TRAILING: DeserializeOwned,
569 ERR: Into<Error> + 'static
570 > WrapMeta<BASE, META> for fn(&BASE, META, $($x,)+ Trailing<TRAILING>) -> BoxFuture<OUT, ERR> {
571 fn wrap_rpc(&self, base: &BASE, params: Params, meta: META) -> BoxFuture<Value, Error> {
572 let len = match require_len(¶ms, $num) {
573 Ok(len) => len,
574 Err(e) => return futures::failed(e).boxed(),
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)) => (self)(base, meta, $($x,)+ Trailing(id)).map(to_value).map_err(Into::into).boxed(),
587 Err(e) => futures::failed(e).boxed(),
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);
645