use crate::types::{Error, Params, Value}; use crate::BoxFuture; use std::fmt; use std::future::Future; use std::sync::Arc; /// Metadata trait pub trait Metadata: Clone + Send + 'static {} impl Metadata for () {} impl Metadata for Option {} impl Metadata for Box {} impl Metadata for Arc {} /// A future-conversion trait. pub trait WrapFuture { /// Convert itself into a boxed future. fn into_future(self) -> BoxFuture>; } impl WrapFuture for Result { fn into_future(self) -> BoxFuture> { Box::pin(async { self }) } } impl WrapFuture for BoxFuture> { fn into_future(self) -> BoxFuture> { self } } /// A synchronous or asynchronous method. pub trait RpcMethodSync: Send + Sync + 'static { /// Call method fn call(&self, params: Params) -> BoxFuture>; } /// Asynchronous Method pub trait RpcMethodSimple: Send + Sync + 'static { /// Output future type Out: Future> + Send; /// Call method fn call(&self, params: Params) -> Self::Out; } /// Asynchronous Method with Metadata pub trait RpcMethod: Send + Sync + 'static { /// Call method fn call(&self, params: Params, meta: T) -> BoxFuture>; } /// Notification pub trait RpcNotificationSimple: Send + Sync + 'static { /// Execute notification fn execute(&self, params: Params); } /// Notification with Metadata pub trait RpcNotification: Send + Sync + 'static { /// Execute notification fn execute(&self, params: Params, meta: T); } /// Possible Remote Procedures with Metadata #[derive(Clone)] pub enum RemoteProcedure { /// A method call Method(Arc>), /// A notification Notification(Arc>), /// An alias to other method, Alias(String), } impl fmt::Debug for RemoteProcedure { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { use self::RemoteProcedure::*; match *self { Method(..) => write!(fmt, ""), Notification(..) => write!(fmt, ""), Alias(ref alias) => write!(fmt, "alias => {:?}", alias), } } } impl RpcMethodSimple for F where F: Fn(Params) -> X, X: Future>, { type Out = X; fn call(&self, params: Params) -> Self::Out { self(params) } } impl RpcMethodSync for F where F: Fn(Params) -> X, X: WrapFuture, { fn call(&self, params: Params) -> BoxFuture> { self(params).into_future() } } impl RpcNotificationSimple for F where F: Fn(Params), { fn execute(&self, params: Params) { self(params) } } impl RpcMethod for F where T: Metadata, F: Fn(Params, T) -> X, X: Future>, { fn call(&self, params: Params, meta: T) -> BoxFuture> { Box::pin(self(params, meta)) } } impl RpcNotification for F where T: Metadata, F: Fn(Params, T), { fn execute(&self, params: Params, meta: T) { self(params, meta) } }