tokio_jsonrpc/
server.rs

1// Copyright 2017 tokio-jsonrpc Developers
2//
3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// http://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7
8//! The [`Server`](trait.Server.html) trait and helpers.
9//!
10//! The `Server` trait for the use by the [`Endpoint`](../endpoint/struct.Endpoint.html) is defined
11//! here. Furthermore, some helpers for convenient creation and composition of servers are
12//! available. Note that not all of these helpers are necessarily zero-cost, at least at this time.
13
14use futures::{Future, IntoFuture};
15use serde::Serialize;
16use serde_json::{to_value, Value};
17
18use endpoint::ServerCtl;
19use message::RpcError;
20
21/// The server endpoint.
22///
23/// This is usually implemented by the end application and provides the actual functionality of the
24/// RPC server. It allows composition of more servers together.
25///
26/// The default implementations of the callbacks return None, indicating that the given method is
27/// not known. It allows implementing only RPCs or only notifications without having to worry about
28/// the other callback. If you want a server that does nothing at all, use
29/// [`Empty`](struct.Empty.html).
30pub trait Server {
31    /// The successfull result of the RPC call.
32    type Success: Serialize;
33    /// The result of the RPC call
34    ///
35    /// Once the future resolves, the value or error is sent to the client as the reply. The reply
36    /// is wrapped automatically.
37    type RpcCallResult: IntoFuture<Item = Self::Success, Error = RpcError> + 'static;
38    /// The result of the RPC call.
39    ///
40    /// As the client doesn't expect anything in return, both the success and error results are
41    /// thrown away and therefore (). However, it still makes sense to distinguish success and
42    /// error.
43    type NotificationResult: IntoFuture<Item = (), Error = ()> + 'static;
44    /// Called when the client requests something.
45    ///
46    /// This is a callback from the [endpoint](../endpoint/struct.Endpoint.html) when the client
47    /// requests something. If the method is unknown, it shall return `None`. This allows
48    /// composition of servers.
49    ///
50    /// Conversion of parameters and handling of errors is up to the implementer of this trait.
51    /// However, the [`jsonrpc_params`](../macro.jsonrpc_params.html) macro may help in that
52    /// regard.
53    fn rpc(
54        &self, _ctl: &ServerCtl, _method: &str, _params: &Option<Value>
55    ) -> Option<Self::RpcCallResult> {
56        None
57    }
58    /// Called when the client sends a notification.
59    ///
60    /// This is a callback from the [endpoint](../endpoint/struct.Endpoint.html) when the client
61    /// requests something. If the method is unknown, it shall return `None`. This allows
62    /// composition of servers.
63    ///
64    /// Conversion of parameters and handling of errors is up to the implementer of this trait.
65    /// However, the [`jsonrpc_params`](../macro.jsonrpc_params.html) macro may help in that
66    /// regard.
67    fn notification(
68        &self, _ctl: &ServerCtl, _method: &str, _params: &Option<Value>
69    ) -> Option<Self::NotificationResult> {
70        None
71    }
72    /// Called when the endpoint is initialized.
73    ///
74    /// It provides a default empty implementation, which can be overriden to hook onto the
75    /// initialization.
76    fn initialized(&self, _ctl: &ServerCtl) {}
77}
78
79/// A RPC server that knows no methods.
80///
81/// You can use this if you want to have a client-only
82/// [Endpoint](../endpoint/struct.Endpoint.html). It simply terminates the server part right away.
83/// Or, more conveniently, use `Endpoint`'s
84/// [`client_only`](../endpoint/struct.Endpoint.html#method.client_only) method.
85pub struct Empty;
86
87impl Server for Empty {
88    type Success = ();
89    type RpcCallResult = Result<(), RpcError>;
90    type NotificationResult = Result<(), ()>;
91    fn initialized(&self, ctl: &ServerCtl) {
92        ctl.terminate();
93    }
94}
95
96/// An RPC server wrapper with dynamic dispatch.
97///
98/// This server wraps another server and converts it into a common ground, so multiple different
99/// servers can be used as trait objects. Basically, it boxes the futures it returns and converts
100/// the result into `serde_json::Value`. It can then be used together with
101/// [`ServerChain`](struct.ServerChain.html) easilly. Note that this conversion incurs
102/// runtime costs.
103pub struct AbstractServer<S: Server>(S);
104
105impl<S: Server> AbstractServer<S> {
106    /// Wraps another server into an abstract server.
107    pub fn new(server: S) -> Self {
108        AbstractServer(server)
109    }
110    /// Unwraps the abstract server and provides the one inside back.
111    pub fn into_inner(self) -> S {
112        self.0
113    }
114}
115
116/// A RPC call result wrapping trait objects.
117pub type BoxRpcCallResult = Box<Future<Item = Value, Error = RpcError>>;
118/// A notification call result wrapping trait objects.
119pub type BoxNotificationResult = Box<Future<Item = (), Error = ()>>;
120
121impl<S: Server> Server for AbstractServer<S> {
122    type Success = Value;
123    type RpcCallResult = BoxRpcCallResult;
124    type NotificationResult = BoxNotificationResult;
125    fn rpc(
126        &self, ctl: &ServerCtl, method: &str, params: &Option<Value>
127    ) -> Option<Self::RpcCallResult> {
128        self.0
129            .rpc(ctl, method, params)
130            .map(|f| -> Box<Future<Item = Value, Error = RpcError>> {
131                let future = f.into_future().map(|result| {
132                    to_value(result)
133                        .expect("Your result type is not convertible to JSON, which is a bug")
134                });
135                Box::new(future)
136            })
137    }
138    fn notification(
139        &self, ctl: &ServerCtl, method: &str, params: &Option<Value>
140    ) -> Option<Self::NotificationResult> {
141        // It seems the type signature is computed from inside the closure and it doesn't fit on
142        // the outside, so we need to declare it manually :-(
143        self.0
144            .notification(ctl, method, params)
145            .map(|f| -> Box<Future<Item = (), Error = ()>> { Box::new(f.into_future()) })
146    }
147    fn initialized(&self, ctl: &ServerCtl) {
148        self.0.initialized(ctl)
149    }
150}
151
152/// A type to store servers as trait objects.
153///
154/// See also [`AbstractServer`](struct.AbstractServer.html) and
155/// [`ServerChain`](struct.ServerChain.html).
156pub type BoxServer = Box<
157    Server<
158        Success = Value,
159        RpcCallResult = Box<Future<Item = Value, Error = RpcError>>,
160        NotificationResult = Box<Future<Item = (), Error = ()>>,
161    >,
162>;
163
164/// A server that chains several other servers.
165///
166/// This composes multiple servers into one. When a notification or an rpc comes, it tries one by
167/// one and passes the call to each of them. If the server provides an answer, the iteration is
168/// stopped and that answer is returned. If the server refuses the given method name, another
169/// server in the chain is tried, until one is found or we run out of servers.
170///
171/// Initialization is called on all the servers.
172///
173/// The [`AbstractServer`](struct.AbstractServer.html) is one of the ways to plug servers with
174/// incompatible future and success types inside.
175pub struct ServerChain(Vec<BoxServer>);
176
177impl ServerChain {
178    /// Construct a new server.
179    pub fn new(subservers: Vec<BoxServer>) -> Self {
180        ServerChain(subservers)
181    }
182    /// Consume the server and return the subservers inside.
183    pub fn into_inner(self) -> Vec<BoxServer> {
184        self.0
185    }
186    /// Iterate through the servers and return the first result that is `Some(_)`.
187    fn iter_chain<R, F: Fn(&BoxServer) -> Option<R>>(&self, f: F) -> Option<R> {
188        for sub in &self.0 {
189            let result = f(sub);
190            if result.is_some() {
191                return result;
192            }
193        }
194        None
195    }
196}
197
198impl Server for ServerChain {
199    type Success = Value;
200    type RpcCallResult = BoxRpcCallResult;
201    type NotificationResult = BoxNotificationResult;
202    fn rpc(
203        &self, ctl: &ServerCtl, method: &str, params: &Option<Value>
204    ) -> Option<Self::RpcCallResult> {
205        self.iter_chain(|sub| sub.rpc(ctl, method, params))
206    }
207    fn notification(
208        &self, ctl: &ServerCtl, method: &str, params: &Option<Value>
209    ) -> Option<Self::NotificationResult> {
210        self.iter_chain(|sub| sub.notification(ctl, method, params))
211    }
212    fn initialized(&self, ctl: &ServerCtl) {
213        for sub in &self.0 {
214            sub.initialized(ctl);
215        }
216    }
217}
218
219/// Parses the parameters of an RPC or a notification.
220///
221/// The [`Server`](server/trait.Server.html) receives `&Option<Value>` as the parameters when its
222/// `notification` or `rpc` method is called and it needs to handle it. This means checking for
223/// validity and converting it to appropriate types. This is tedious.
224///
225/// This macro helps with that. In it's basic usage, you pass the received parameters and parameter
226/// definitions for what you want and receive a tuple of converted ones. In case the parameters are
227/// invalid, it returns early with an `Some(IntoFuture<_, Error = RpcError>)` directly from your
228/// function (which is the return type of the callbacks).
229///
230/// Note that while this macro may be used directly, the macro
231/// [`jsonrpc_server_impl`](macro.jsonrpc_server_impl.html) which builds the whole `Server` trait
232/// implementation uses it internally and it is the preferred way to use it.
233///
234/// By default, it accepts both parameters passed by a name (inside a JSON object) or by position
235/// (inside an array). If you insist your clients must use named or positional parameters, prefix
236/// the parameter definitions by `named` or `positional` respectively. The `positional` omits the
237/// parameter names in the definitions.
238///
239/// This also handles optional arguments in the `named` case (and when auto-detecting and a JSON
240/// object is provided).
241///
242/// If an empty parameter definition is provided, the macro checks that no parameters were sent
243/// (accepts no parameters sent, `null` sent as parameters and an empty object or array).
244///
245/// If a single parameter is passed, in addition to trying positional and named parameters, the
246/// macro tries to convert the whole `Value` into the given type. This allows you to ask for
247/// a structure that holds all the named parameters.
248///
249/// If you want to force the single parameter conversion of the whole `Value`, you can use the
250/// macro as `jsonrpc_params!(params, single Type)`. However, in this case it returns
251/// `Result<Type, RpcError>` ‒ since it is expected you might want to try both named and
252/// positional decoding yourself. Also, it expects `&Value`, not `&Option<Value>`.
253///
254/// You can also force the macro to return the `Result<(Type, Type, ...), RpcError>` if you prefer,
255/// by prefixing the parameter definitions with the `wrap` token.
256///
257/// The macro has other variants than the mentioned here. They are mostly used internally by the
258/// macro itself and aren't meant to be used directly.
259///
260/// # Examples
261///
262/// Basic usage, parse an integer and a boolean:
263///
264/// ```rust
265/// # #[macro_use] extern crate tokio_jsonrpc;
266/// # #[macro_use] extern crate serde_json;
267/// # use tokio_jsonrpc::message::RpcError;
268/// # use serde_json::Value;
269/// fn parse(params: &Option<Value>) -> Option<Result<(i32, bool), RpcError>> {
270///     Some(Ok(jsonrpc_params!(params, "num" => i32, "b" => bool)))
271/// }
272///
273/// # fn main() {
274/// assert_eq!((42, true), parse(&Some(json!([42, true]))).unwrap().unwrap());
275/// assert_eq!((42, true), parse(&Some(json!({"num": 42, "b": true}))).unwrap().unwrap());
276/// parse(&None).unwrap().unwrap_err();
277/// parse(&Some(json!({"num": "hello", "b": false}))).unwrap().unwrap_err();
278/// // Return by the macro instead of exit
279/// assert_eq!((42, true), jsonrpc_params!(&Some(json!({"num": 42, "b": true})),
280///                                        wrap "num" => i32, "b" => bool).unwrap());
281/// jsonrpc_params!(&None, wrap "num" => i32, "b" => bool).unwrap_err();
282/// # }
283/// ```
284///
285/// Usage with enforcing named parameters. Also, the integer is optional. Enforcing positional
286/// works in a similar way, with the `positional` token.
287///
288/// ```rust
289/// # #[macro_use] extern crate tokio_jsonrpc;
290/// # #[macro_use] extern crate serde_json;
291/// # use tokio_jsonrpc::message::RpcError;
292/// # use serde_json::Value;
293/// fn parse(params: &Option<Value>) -> Option<Result<(Option<i32>, bool), RpcError>> {
294///     Some(Ok(jsonrpc_params!(params, named "num" => Option<i32>, "b" => bool)))
295/// }
296///
297/// # fn main() {
298/// parse(&Some(json!([42, true]))).unwrap().unwrap_err();
299/// assert_eq!((Some(42), true), parse(&Some(json!({"num": 42, "b": true}))).unwrap().unwrap());
300/// assert_eq!((None, false),
301///            parse(&Some(json!({"b": false, "extra": "ignored"}))).unwrap().unwrap());
302/// parse(&None).unwrap().unwrap_err();
303/// parse(&Some(json!({"num": "hello", "b": false}))).unwrap().unwrap_err();
304/// # }
305/// ```
306///
307/// Enforcing positional parameters:
308///
309/// ```rust
310/// # #[macro_use] extern crate tokio_jsonrpc;
311/// # #[macro_use] extern crate serde_json;
312/// # use tokio_jsonrpc::message::RpcError;
313/// # use serde_json::Value;
314/// fn parse(params: &Option<Value>) -> Option<Result<(i32, bool), RpcError>> {
315///     Some(Ok(jsonrpc_params!(params, positional i32, bool)))
316/// }
317///
318/// # fn main() {
319/// assert_eq!((42, true), parse(&Some(json!([42, true]))).unwrap().unwrap());
320/// # }
321/// ```
322///
323/// Decoding into a structure works like this:
324///
325/// ```rust
326/// # #[macro_use] extern crate tokio_jsonrpc;
327/// # #[macro_use] extern crate serde_json;
328/// # #[macro_use] extern crate serde_derive;
329/// # use tokio_jsonrpc::message::RpcError;
330/// # use serde_json::Value;
331///
332/// #[derive(PartialEq, Debug, Deserialize)]
333/// struct Params {
334///     num: Option<i32>,
335///     b: bool,
336/// }
337///
338/// fn parse(params: &Option<Value>) -> Option<Result<Params, RpcError>> {
339///     let (params,) = jsonrpc_params!(params, "params" => Params);
340///     Some(Ok(params))
341/// }
342///
343/// # fn main() {
344/// let expected = Params {
345///     num: Some(42),
346///     b: true,
347/// };
348/// let expected_optional = Params {
349///     num: None,
350///     b: false,
351/// };
352///
353/// assert_eq!(expected, parse(&Some(json!([42, true]))).unwrap().unwrap());
354/// assert_eq!(expected, parse(&Some(json!({"num": 42, "b": true}))).unwrap().unwrap());
355/// assert_eq!(expected_optional, parse(&Some(json!({"b": false}))).unwrap().unwrap());
356/// // This is accepted mostly as a side effect.
357/// assert_eq!(expected, parse(&Some(json!([{"num": 42, "b": true}]))).unwrap().unwrap());
358/// // As is this.
359/// assert_eq!(expected, parse(&Some(json!({"params": {"num": 42, "b": true}}))).unwrap().unwrap());
360/// // If you mind the above limitations, you can ask directly for a single value decoding.
361/// // That returs a Result directly.
362/// assert_eq!(expected,
363///            jsonrpc_params!(&json!({"num": 42, "b": true}), single Params).unwrap());
364/// jsonrpc_params!(&json!([{"num": 42, "b": true}]), single Params).unwrap_err();
365/// # }
366/// ```
367#[macro_export]
368macro_rules! jsonrpc_params {
369    // When the user asks for no params to be present. In that case we allow no params or null or
370    // empty array or dictionary, for better compatibility. This is probably more benevolent than
371    // the spec allows.
372    ( $value:expr, ) => {
373        match *$value {
374            // Accept the empty values
375            None |
376            Some($crate::macro_exports::Value::Null) => (),
377            Some($crate::macro_exports::Value::Array(ref arr)) if arr.len() == 0 => (),
378            Some($crate::macro_exports::Value::Object(ref obj)) if obj.len() == 0 => (),
379            // If it's anything else, complain
380            _ => {
381                return Some(Err($crate::message::RpcError::
382                                invalid_params(Some("Expected no params".to_owned()))).into());
383            },
384        }
385    };
386    // A convenience conversion
387    ( $value:expr ) => { jsonrpc_params!($value,) };
388    // An internal helper to decode a single variable and provide a Result instead of returning
389    // from the function.
390    ( $value:expr, single $vartype:ty ) => {{
391        // Fix the type
392        let val: &$crate::macro_exports::Value = $value;
393        $crate::macro_exports::from_value::<$vartype>(val.clone()).map_err(|e| {
394            $crate::message::RpcError::invalid_params(Some(format!("Incompatible type: {}", e)))
395        })
396    }};
397    // A helper to count number of arguments
398    ( arity $head:ty ) => { 1 };
399    ( arity $head:ty, $( $tail:ty ),* ) => { 1 + jsonrpc_params!(arity $( $tail ),*) };
400    // A helper to recurse on decoding of positional arguments
401    ( $spl:expr, accum ( $( $result:tt )* ), positional_decode $vtype:ty ) => {
402        ( $( $result )*
403            {
404                let spl: &[$crate::macro_exports::Value] = $spl;
405                match jsonrpc_params!(&spl[0], single $vtype) {
406                    Ok(result) => result,
407                    Err(e) => return Some(Err(e)),
408                }
409            },
410        )
411    };
412    ( $spl:expr, accum ( $( $result:tt )* ),
413      positional_decode $htype:ty, $( $ttype:ty ),+ ) => {{
414        let spl: &[$crate::macro_exports::Value] = $spl;
415        jsonrpc_params!(&spl[1..], accum (
416            $( $result )*
417            {
418                match jsonrpc_params!(&spl[0], single $htype) {
419                    Ok(result) => result,
420                    Err(e) => return Some(Err(e)),
421                }
422            },
423        ), positional_decode $( $ttype ),+ )
424    }};
425    // Possibly multiple arguments, enforcing positional coding (in an array)
426    // It uses recursion to count and access the items in the vector
427    ( $value:expr, positional $( $vartype:ty ),+ ) => {{
428        let val: &$crate::macro_exports::Option<$crate::macro_exports::Value> = $value;
429        match *val {
430            None => return Some(Err($crate::message::RpcError::
431                                    invalid_params(Some("Expected parameters".to_owned()))).into()),
432            Some($crate::macro_exports::Value::Array(ref vec)) => {
433                let cnt = jsonrpc_params!(arity $( $vartype ),+);
434                if cnt != vec.len() {
435                    let err = format!("Wrong number of parameters: expected: {}, got: {}", cnt,
436                                      vec.len());
437                    return Some(Err($crate::message::RpcError::invalid_params(Some(err))).into());
438                }
439                let spl: &[$crate::macro_exports::Value] = &vec[..];
440                jsonrpc_params!(spl, accum (), positional_decode $( $vartype ),+)
441            },
442            Some(_) => {
443                return Some(Err($crate::message::RpcError::
444                                invalid_params(Some("Expected an array as parameters".to_owned())))
445                            .into());
446            },
447        }
448    }};
449    // Decode named arguments.
450    // It can handle optional arguments in a way, but it has its limits (eg. a non-optional string
451    // defaults to an empty one if it is missing).
452    ( $value:expr, named $( $varname:expr => $vartype:ty ),+ ) => {{
453        let val: &$crate::macro_exports::Option<$crate::macro_exports::Value> = $value;
454        match *val {
455            None => return Some(Err($crate::message::RpcError::
456                                    invalid_params(Some("Expected parameters".to_owned()))).into()),
457            Some($crate::macro_exports::Value::Object(ref map)) => {
458                (
459                    $(
460                        {
461                            // Yes, stupid borrow checker… can't we get a global constant that
462                            // never gets dropped?
463                            let null = $crate::macro_exports::Value::Null;
464                            let subval = map.get($varname).unwrap_or(&null);
465                            match jsonrpc_params!(subval, single $vartype) {
466                                Ok(result) => result,
467                                Err(e) => return Some(Err(e)),
468                            }
469                        },
470                    )+
471                )
472            },
473            Some(_) => {
474                return Some(Err($crate::message::RpcError::
475                                invalid_params(Some("Expected an object as parameters".to_owned())))
476                            .into());
477            },
478        }
479    }};
480    // Decode params, decide if named or positional based on what arrived
481    ( $value:expr, decide $( $varname:expr => $vartype:ty ),+ ) => {{
482        let val: &$crate::macro_exports::Option<$crate::macro_exports::Value> = $value;
483        match *val {
484            None => return Some(Err($crate::message::RpcError::
485                                    invalid_params(Some("Expected parameters".to_owned()))).into()),
486            Some($crate::macro_exports::Value::Array(_)) => {
487                jsonrpc_params!(val, positional $( $vartype ),+)
488            },
489            Some($crate::macro_exports::Value::Object(_)) => {
490                jsonrpc_params!(val, named $( $varname => $vartype ),+)
491            },
492            Some(_) => {
493                return Some(Err($crate::message::RpcError::
494                                invalid_params(Some("Expected an object or an array as parameters"
495                                                    .to_owned()))).into());
496            },
497        }
498    }};
499    // A special case for a single param.
500    //
501    // We allow decoding it directly, mostly to support users with a complex all-params structure.
502    ( $value:expr, $varname:expr => $vartype:ty ) => {{
503        let val: &$crate::macro_exports::Option<$crate::macro_exports::Value> = $value;
504        // First try decoding directly
505        let single = val.as_ref().map(|val| jsonrpc_params!(val, single $vartype));
506        if let Some(Ok(result)) = single {
507            (result,)
508        } else {
509            // If direct single decoding didn't work, try the usual multi-param way.
510            jsonrpc_params!(val, decide $varname => $vartype)
511        }
512    }};
513    // Propagate multiple params.
514    ( $value:expr, $( $varname:expr => $vartype:ty ),+ ) => {
515        jsonrpc_params!($value, decide $( $varname => $vartype ),+)
516    };
517    // Return multiple values as a result
518    ( $value:expr, wrap $( $varname:expr => $vartype:ty ),+ ) => {
519        {
520            fn convert(params: &$crate::macro_exports::Option<$crate::macro_exports::Value>)
521                       -> $crate::macro_exports::Option<
522                           $crate::macro_exports::Result<($( $vartype, )+),
523                                                         $crate::message::RpcError>> {
524                Some(Ok(jsonrpc_params!(params, $( $varname => $vartype ),+)))
525            }
526            convert($value).unwrap()
527        }
528    };
529    ( $value:expr, wrap named $( $varname:expr => $vartype:ty ),+ ) => {
530        {
531            fn convert(params: &$crate::macro_exports::Option<$crate::macro_exports::Value>)
532                       -> $crate::macro_exports::Option<
533                           $crate::macro_exports::Result<($( $vartype, )+),
534                                                          $crate::message::RpcError>> {
535                Some(Ok(jsonrpc_params!(params, named $( $varname => $vartype ),+)))
536            }
537            convert($value).unwrap()
538        }
539    };
540    ( $value:expr, wrap positional $( $vartype:ty ),+ ) => {
541        {
542            fn convert(params: &$crate::macro_exports::Option<$crate::macro_exports::Value>)
543                       -> $crate::macro_exports::Option<
544                           $crate::macro_exports::Result<($( $vartype, )+),
545                                                         $crate::message::RpcError>> {
546                Some(Ok(jsonrpc_params!(params, positional $( $vartype ),+)))
547            }
548            convert($value).unwrap()
549        }
550    };
551}
552
553/*
554 The intention:
555
556 jsonrpc_server! {
557    X {
558        rpcs {
559            hello(i: usize); // Will call x.hello(i), convert parameters, convert result…
560        }
561        notifications {
562            hi(x: String); // Will call x.hi(…)
563        }
564        init // Will call x.init
565    }
566 }
567
568
569   */
570
571/*
572trace_macros!(true);
573// TODO: We want to be able to accept arrays of different kinds of data, possibly alternatives…
574macro_rules! json_param {
575    ( (), $value:ident ) => { () };
576    ( $param:ty, $value:ident ) => {
577        match *$value {
578            None => unimplemented!(),
579            Some(ref v) => {
580                let result: Result<$param, _> = from_value(v.clone());
581                match result {
582                    Ok(r) => r,
583                    Err(_) => unimplemented!(),
584                }
585            },
586        }
587    }
588}
589macro_rules! json_rpc_impl {
590    ( $( $method:pat => ($param:ty) $code:block ),* ) => {
591        // TODO Use $crate for the types and absolute paths for Value
592        fn rpc(&self, ctl: &ServerCtl, method: &str, param: &Option<Value>) ->
593        Option<Self::RpcCallResult> {
594            match method {
595                $( $method => {
596                    let input = json_param!($param, param);
597                    let result = $code;
598                    let mapped = result.map(|r| to_value(r).expect("Error converting RPC result"));
599                    Some(Box::new(mapped.into_future()))
600                }, )*
601                _ => None,
602            }
603        }
604    };
605}
606
607    struct X;
608
609    impl Server for X {
610        type Success = Value;
611        type RpcCallResult = BoxRpcCallResult;
612        type NotificationResult = BoxNotificationResult;
613        json_rpc_impl!{
614            "test" => (usize) {
615                Ok(42)
616            },
617            "another" => (bool) {
618                Ok("Hello".to_owned())
619            }
620        }
621    }
622    */
623
624#[cfg(test)]
625mod tests {
626    use std::cell::{Cell, RefCell};
627    use serde_json::Map;
628
629    use super::*;
630
631    /// Check the empty server is somewhat sane.
632    #[test]
633    fn empty() {
634        let server = Empty;
635        let (ctl, dropped, _killed) = ServerCtl::new_test();
636        // As we can't reasonably check all possible method names, do so for just a bunch
637        for method in ["method", "notification", "check"].iter() {
638            assert!(server.rpc(&ctl, method, &None).is_none());
639            assert!(server.notification(&ctl, method, &None).is_none());
640        }
641        // It terminates the ctl on the server side on initialization
642        server.initialized(&ctl);
643        dropped.wait().unwrap();
644    }
645
646    /// A server that logs what has been called.
647    #[derive(Default, Debug, PartialEq)]
648    struct LogServer {
649        serial: Cell<usize>,
650        rpc: RefCell<Vec<usize>>,
651        notification: RefCell<Vec<usize>>,
652        initialized: RefCell<Vec<usize>>,
653    }
654
655    impl LogServer {
656        fn update(&self, what: &RefCell<Vec<usize>>) {
657            let serial = self.serial.get() + 1;
658            self.serial.set(serial);
659            what.borrow_mut().push(serial);
660        }
661    }
662
663    impl Server for LogServer {
664        type Success = bool;
665        type RpcCallResult = Result<bool, RpcError>;
666        type NotificationResult = Result<(), ()>;
667        fn rpc(
668            &self, _ctl: &ServerCtl, method: &str, params: &Option<Value>
669        ) -> Option<Self::RpcCallResult> {
670            self.update(&self.rpc);
671            match method {
672                "test" => {
673                    assert!(params.is_none());
674                    Some(Ok(true))
675                },
676                _ => None,
677            }
678        }
679        fn notification(
680            &self, _ctl: &ServerCtl, method: &str, params: &Option<Value>
681        ) -> Option<Self::NotificationResult> {
682            self.update(&self.notification);
683            assert!(params.is_none());
684            match method {
685                "notification" => Some(Ok(())),
686                _ => None,
687            }
688        }
689        fn initialized(&self, _ctl: &ServerCtl) {
690            self.update(&self.initialized);
691        }
692    }
693
694    /// Testing of the abstract server
695    ///
696    /// Just checking the data gets through and calling everything, there's nothing much to test
697    /// anyway.
698    #[test]
699    fn abstract_server() {
700        let log_server = LogServer::default();
701        let abstract_server = AbstractServer::new(log_server);
702        let (ctl, _, _) = ServerCtl::new_test();
703        let rpc_result = abstract_server
704            .rpc(&ctl, "test", &None)
705            .unwrap()
706            .wait()
707            .unwrap();
708        assert_eq!(Value::Bool(true), rpc_result);
709        abstract_server
710            .notification(&ctl, "notification", &None)
711            .unwrap()
712            .wait()
713            .unwrap();
714        assert!(abstract_server.rpc(&ctl, "another", &None).is_none());
715        assert!(
716            abstract_server
717                .notification(&ctl, "another", &None)
718                .is_none()
719        );
720        abstract_server.initialized(&ctl);
721        let log_server = abstract_server.into_inner();
722        let expected = LogServer {
723            serial: Cell::new(5),
724            rpc: RefCell::new(vec![1, 3]),
725            notification: RefCell::new(vec![2, 4]),
726            initialized: RefCell::new(vec![5]),
727        };
728        assert_eq!(expected, log_server);
729    }
730
731    struct AnotherServer;
732
733    impl Server for AnotherServer {
734        type Success = usize;
735        type RpcCallResult = Result<usize, RpcError>;
736        type NotificationResult = Result<(), ()>;
737        fn rpc(
738            &self, _ctl: &ServerCtl, method: &str, params: &Option<Value>
739        ) -> Option<Self::RpcCallResult> {
740            assert!(params.as_ref().unwrap().is_null());
741            match method {
742                "another" => Some(Ok(42)),
743                _ => None,
744            }
745        }
746        // Ignore the other methods
747    }
748
749    /// Test the chain.
750    ///
751    /// By the asserts on params in the servers we check that only whan should be called is.
752    #[test]
753    fn chain() {
754        let empty_server = Empty;
755        let log_server = LogServer::default();
756        let another_server = AnotherServer;
757        let (ctl, dropped, _killed) = ServerCtl::new_test();
758        let chain = ServerChain::new(vec![
759            Box::new(AbstractServer::new(empty_server)),
760            Box::new(AbstractServer::new(log_server)),
761            Box::new(AbstractServer::new(another_server)),
762        ]);
763        chain.initialized(&ctl);
764        dropped.wait().unwrap();
765        assert_eq!(
766            Value::Bool(true),
767            chain.rpc(&ctl, "test", &None).unwrap().wait().unwrap()
768        );
769        assert_eq!(
770            json!(42),
771            chain
772                .rpc(&ctl, "another", &Some(Value::Null))
773                .unwrap()
774                .wait()
775                .unwrap()
776        );
777        assert!(chain.rpc(&ctl, "wrong", &Some(Value::Null)).is_none());
778        chain
779            .notification(&ctl, "notification", &None)
780            .unwrap()
781            .wait()
782            .unwrap();
783        assert!(chain.notification(&ctl, "another", &None).is_none());
784        // It would be great to check what is logged inside the log server. But downcasting a trait
785        // object seems to be a big pain and probably isn't worth it here.
786    }
787
788    /// A guard object that panics when dropped unless it has been disarmed first.
789    ///
790    /// We use it to check the macro we test didn't short-circuit the test by returning early. Note
791    /// that it causes a double panic if the test fails (in that case you want to temporarily
792    /// remove the panic guard from that test).
793    ///
794    /// Most of the following tests don't need it, as they call the macro indirectly, by wrapping
795    /// it into a function (and such function can't return in the caller).
796    struct PanicGuard(bool);
797
798    impl PanicGuard {
799        /// A constructor. Creates an armed guerd.
800        fn new() -> Self {
801            PanicGuard(true)
802        }
803        /// Disarm the guard → it won't panic when dropped.
804        fn disarm(&mut self) {
805            self.0 = false;
806        }
807    }
808
809    impl Drop for PanicGuard {
810        fn drop(&mut self) {
811            if self.0 {
812                panic!("PanicGuard dropped without being disarmed");
813            }
814        }
815    }
816
817    /// Test the panic guard itself
818    #[test]
819    #[should_panic]
820    fn panic_guard() {
821        PanicGuard::new();
822    }
823
824    /// Expect no params and return whanever we got from the macro.
825    ///
826    /// It is a separate function so the return error thing from the macro doesn't end the test
827    /// prematurely (actually, it wouldn't, as the return type doesn't match).
828    fn expect_no_params(params: &Option<Value>) -> Option<Result<(), RpcError>> {
829        // Check that we can actually assign it somewhere (this may be needed in other macros later
830        // on.
831        let () = jsonrpc_params!(params,);
832        Some(Ok(()))
833    }
834
835    /// Test the jsonrpc_params macro when we expect no parameters.
836    #[test]
837    fn params_macro_none() {
838        // These are legal no-params, at least for us
839        expect_no_params(&None).unwrap().unwrap();
840        expect_no_params(&Some(Value::Null)).unwrap().unwrap();
841        expect_no_params(&Some(Value::Array(Vec::new())))
842            .unwrap()
843            .unwrap();
844        expect_no_params(&Some(Value::Object(Map::new())))
845            .unwrap()
846            .unwrap();
847        // Some illegal values
848        expect_no_params(&Some(Value::Bool(true)))
849            .unwrap()
850            .unwrap_err();
851        expect_no_params(&Some(json!([42, "hello"])))
852            .unwrap()
853            .unwrap_err();
854        expect_no_params(&Some(json!({"hello": 42})))
855            .unwrap()
856            .unwrap_err();
857        expect_no_params(&Some(json!(42))).unwrap().unwrap_err();
858        expect_no_params(&Some(json!("hello")))
859            .unwrap()
860            .unwrap_err();
861    }
862
863    /// Test the single-param jsonrpc_params helper variant.
864    #[test]
865    fn single_param() {
866        let mut guard = PanicGuard::new();
867        // A valid conversion
868        // Make sure the return type fits
869        let result: Result<bool, RpcError> = jsonrpc_params!(&Value::Bool(true), single bool);
870        assert!(result.unwrap());
871        // Some invalid conversions
872        jsonrpc_params!(&Value::Null, single bool).unwrap_err();
873        jsonrpc_params!(&Value::Array(Vec::new()), single bool).unwrap_err();
874        guard.disarm();
875    }
876
877    /// A helper function to decode two values as positional arguments.
878    ///
879    /// This is to prevent attempt to return errors from within the test function.
880    fn bool_str_positional(value: &Option<Value>) -> Option<Result<(bool, String), RpcError>> {
881        let (b, s) = jsonrpc_params!(value, positional bool, String);
882        Some(Ok((b, s)))
883    }
884
885    /// Like above, but with only a single variable.
886    ///
887    /// As single-values are handled slightly differently at a syntax level (eg, a tuple with only
888    /// one element needs a terminating comma) and also differently in the macro (they are
889    /// sometimes the ends of recursion), we mostly want to check it compiles.
890    ///
891    /// It also checks we don't get confused with an array inside the parameter array.
892    fn single_positional(value: &Option<Value>) -> Option<Result<Vec<String>, RpcError>> {
893        let (r,) = jsonrpc_params!(value, positional Vec<String>);
894        Some(Ok(r))
895    }
896
897    /// Test decoding positional arguments.
898    #[test]
899    fn positional() {
900        // Some that don't match
901        bool_str_positional(&None).unwrap().unwrap_err();
902        bool_str_positional(&Some(Value::Null))
903            .unwrap()
904            .unwrap_err();
905        bool_str_positional(&Some(Value::Bool(true)))
906            .unwrap()
907            .unwrap_err();
908        bool_str_positional(&Some(json!({"b": true, "s": "hello"})))
909            .unwrap()
910            .unwrap_err();
911        bool_str_positional(&Some(json!([true])))
912            .unwrap()
913            .unwrap_err();
914        bool_str_positional(&Some(json!([true, "hello", false])))
915            .unwrap()
916            .unwrap_err();
917        bool_str_positional(&Some(json!([true, true])))
918            .unwrap()
919            .unwrap_err();
920        // This one should be fine
921        assert_eq!(
922            (true, "hello".to_owned()),
923            bool_str_positional(&Some(json!([true, "hello"])))
924                .unwrap()
925                .unwrap()
926        );
927
928        single_positional(&None).unwrap().unwrap_err();
929        // We need two nested arrays
930        single_positional(&Some(json!(["Hello"])))
931            .unwrap()
932            .unwrap_err();
933        assert!(
934            single_positional(&Some(json!([[]])))
935                .unwrap()
936                .unwrap()
937                .is_empty()
938        );
939        assert_eq!(
940            vec!["hello", "world"],
941            single_positional(&Some(json!([["hello", "world"]])))
942                .unwrap()
943                .unwrap()
944        );
945    }
946
947    /// Similar to `positional`, but with using the macro wrap support to return a result.
948    #[test]
949    fn positional_direct() {
950        let mut guard = PanicGuard::new();
951        jsonrpc_params!(&None, wrap positional bool, String).unwrap_err();
952        jsonrpc_params!(&Some(Value::Null), wrap positional bool, String).unwrap_err();
953        jsonrpc_params!(&Some(Value::Bool(true)), wrap positional bool, String).unwrap_err();
954        jsonrpc_params!(&Some(json!({"b": true, "s": "hello"})), wrap positional bool, String)
955            .unwrap_err();
956        assert_eq!(
957            (true, "hello".to_owned()),
958            jsonrpc_params!(&Some(json!([true, "hello"])),
959                                   wrap positional bool, String)
960                .unwrap()
961        );
962        guard.disarm();
963    }
964
965    /// Helper function to decode two values as named arguments
966    fn bool_str_named(value: &Option<Value>) -> Option<Result<(bool, String), RpcError>> {
967        let (b, s) = jsonrpc_params!(value, named "b" => bool, "s" => String);
968        Some(Ok((b, s)))
969    }
970
971    #[derive(Deserialize, Debug, Eq, PartialEq)]
972    struct TestStruct {
973        x: i32,
974    }
975
976    /// Like above, but with only one parameter.
977    fn single_named(value: &Option<Value>) -> Option<Result<TestStruct, RpcError>> {
978        let (ts,) = jsonrpc_params!(value, named "ts" => TestStruct);
979        Some(Ok(ts))
980    }
981
982    /// Test an optional value might be missing.
983    fn optional_named(value: &Option<Value>) -> Option<Result<Option<u32>, RpcError>> {
984        let (ov,) = jsonrpc_params!(value, named "ov" => Option<u32>);
985        Some(Ok(ov))
986    }
987
988    /// Test decoding named arguments
989    #[test]
990    fn named() {
991        bool_str_named(&None).unwrap().unwrap_err();
992        bool_str_named(&Some(Value::Null)).unwrap().unwrap_err();
993        bool_str_named(&Some(Value::Bool(true)))
994            .unwrap()
995            .unwrap_err();
996        bool_str_named(&Some(json!([true, "hello"])))
997            .unwrap()
998            .unwrap_err();
999        bool_str_named(&Some(json!({"b": true, "s": 42})))
1000            .unwrap()
1001            .unwrap_err();
1002        // FIXME: This fails, as serde_json considers Value::Null to be an empty string
1003        //bool_str_named(&Some(json!({"b": true}))).unwrap_err();
1004        bool_str_named(&Some(json!({"s": "hello"})))
1005            .unwrap()
1006            .unwrap_err();
1007        assert_eq!(
1008            (true, "hello".to_owned()),
1009            bool_str_named(&Some(json!({"b": true, "s": "hello"})))
1010                .unwrap()
1011                .unwrap()
1012        );
1013        // FIXME: We currently don't know how to check against extra params
1014        assert_eq!(
1015            (true, "hello".to_owned()),
1016            bool_str_named(&Some(json!({"b": true, "s": "hello", "x": 42})))
1017                .unwrap()
1018                .unwrap()
1019        );
1020
1021        single_named(&None).unwrap().unwrap_err();
1022        single_named(&Some(json!({"ts": 42}))).unwrap().unwrap_err();
1023        single_named(&Some(json!({"ts": {"x": 42}})))
1024            .unwrap()
1025            .unwrap();
1026
1027        optional_named(&None).unwrap().unwrap_err();
1028        optional_named(&Some(json!([]))).unwrap().unwrap_err();
1029        assert_eq!(
1030            Some(42),
1031            optional_named(&Some(json!({"ov": 42}))).unwrap().unwrap()
1032        );
1033        assert_eq!(None, optional_named(&Some(json!({}))).unwrap().unwrap());
1034    }
1035
1036    /// Like `named`, but using auto-wrapping support from the macro.
1037    #[test]
1038    fn named_direct() {
1039        let mut guard = PanicGuard::new();
1040        jsonrpc_params!(&None, wrap named "b" => bool, "s" => String).unwrap_err();
1041        jsonrpc_params!(&Some(Value::Null), wrap named "b" => bool, "s" => String).unwrap_err();
1042        jsonrpc_params!(&Some(Value::Bool(true)),
1043                        wrap named "b" => bool, "s" => String)
1044            .unwrap_err();
1045        assert_eq!(
1046            (true, "hello".to_owned()),
1047            jsonrpc_params!(&Some(json!({"b": true, "s": "hello"})),
1048                                   wrap "b" => bool, "s" => String)
1049                .unwrap()
1050        );
1051        jsonrpc_params!(&Some(json!([true, "hello"])), wrap named "b" => bool, "s" => String)
1052            .unwrap_err();
1053        guard.disarm();
1054    }
1055
1056    /// A helper function to decode two parameters.
1057    ///
1058    /// The decoding decides how to do so based on what arrived.
1059    fn bool_str(value: &Option<Value>) -> Option<Result<(bool, String), RpcError>> {
1060        let (b, s) = jsonrpc_params!(value, "b" => bool, "s" => String);
1061        Some(Ok((b, s)))
1062    }
1063
1064    /// Test decoding parameters when it decides itself how.
1065    #[test]
1066    fn decide() {
1067        bool_str(&None).unwrap().unwrap_err();
1068        bool_str(&Some(Value::Null)).unwrap().unwrap_err();
1069        bool_str(&Some(Value::Bool(true))).unwrap().unwrap_err();
1070        assert_eq!(
1071            (true, "hello".to_owned()),
1072            bool_str_named(&Some(json!({"b": true, "s": "hello"})))
1073                .unwrap()
1074                .unwrap()
1075        );
1076        assert_eq!(
1077            (true, "hello".to_owned()),
1078            bool_str_positional(&Some(json!([true, "hello"])))
1079                .unwrap()
1080                .unwrap()
1081        );
1082    }
1083
1084    /// Like `decide`, but with auto-wrapping support from the macro.
1085    #[test]
1086    fn decide_direct() {
1087        let mut guard = PanicGuard::new();
1088        jsonrpc_params!(&None, wrap "b" => bool, "s" => String).unwrap_err();
1089        jsonrpc_params!(&Some(Value::Null), wrap "b" => bool, "s" => String).unwrap_err();
1090        jsonrpc_params!(&Some(Value::Bool(true)), wrap "b" => bool, "s" => String).unwrap_err();
1091        assert_eq!(
1092            (true, "hello".to_owned()),
1093            jsonrpc_params!(&Some(json!({"b": true, "s": "hello"})),
1094                                   wrap "b" => bool, "s" => String)
1095                .unwrap()
1096        );
1097        assert_eq!(
1098            (true, "hello".to_owned()),
1099            jsonrpc_params!(&Some(json!([true, "hello"])),
1100                                   wrap "b" => bool, "s" => String)
1101                .unwrap()
1102        );
1103        guard.disarm();
1104    }
1105
1106    /// A helper for the `decide_single` test.
1107    fn decode_test_struct(value: &Option<Value>) -> Option<Result<TestStruct, RpcError>> {
1108        let (ts,) = jsonrpc_params!(value, "ts" => TestStruct);
1109        Some(Ok(ts))
1110    }
1111
1112    /// Similar to `decide`, but with a single parameter.
1113    ///
1114    /// The single parameter is special, since it can decode the parameters structure directly.
1115    /// This is to support the user having an all-encompassing parameter struct (possibly with all
1116    /// optional/default/renaming tweaks done through fine-tuning serde).
1117    #[test]
1118    fn decide_single() {
1119        decode_test_struct(&None).unwrap().unwrap_err();
1120        decode_test_struct(&Some(Value::Null)).unwrap().unwrap_err();
1121        decode_test_struct(&Some(Value::Bool(true)))
1122            .unwrap()
1123            .unwrap_err();
1124
1125        // Encoded as an array
1126        assert_eq!(
1127            TestStruct { x: 42 },
1128            decode_test_struct(&Some(json!([{"x": 42}])))
1129                .unwrap()
1130                .unwrap()
1131        );
1132        // Encoded as an object
1133        assert_eq!(
1134            TestStruct { x: 42 },
1135            decode_test_struct(&Some(json!({"ts": {"x": 42}})))
1136                .unwrap()
1137                .unwrap()
1138        );
1139        // Encoded directly as the parameters structure
1140        assert_eq!(
1141            TestStruct { x: 42 },
1142            decode_test_struct(&Some(json!({"x": 42})))
1143                .unwrap()
1144                .unwrap()
1145        );
1146    }
1147}