ezrpc 0.1.1

Ergonomic, flexible and Zero-cost RPC framework
Documentation
/// The ezrpc macro, for RPC intefaces declaration
#[macro_export]
macro_rules! ezrpc {
    (
        $(fn $fname:ident$(<$lf:lifetime>)?($(*$ss:ident,)? $($arg:ident: $type:ty),*) $(-> $ret:ty)? $([$n:expr])?;)*
    ) => {
        #[macro_export]
        macro_rules! init_service {
            ($trait:ty, $t:ty) => {
                impl $t {
                    pub fn init_service(service: &$crate::MappedService<Self>) {
                        use $trait as Service;
                        $($crate::ezrpc!(@add service, Self, $fname $(= $n)?);)*
                    }

                    pub fn new_service(self) -> $crate::MappedService<Self> {
                        let service = $crate::MappedService::<Self>::new(self);
                        Self::init_service(&service);
                        service
                    }
                }
            };
        }

        pub use init_service;

        #[allow(non_snake_case)]
        pub trait Service: Send + Sync + Sized + 'static {
            $($crate::ezrpc!{@serv ($fname, $(<$lf>)? $(*$ss,)? $($arg: $type),*) $(-> $ret)?})*
        }

        #[allow(non_snake_case)]
        pub trait SessionMethod {
            $($crate::ezrpc!{@decl ($fname, $(<$lf>)? $($arg: $type),*) $(-> $ret)?})*
        }

        #[allow(non_snake_case)]
        impl SessionMethod for $crate::Session {
            $($crate::ezrpc!{@call ($fname $(= $n)?, $(<$lf>)? $($arg: $type),*) $(-> $ret)?})*
        }
    };

    (@method $fname:ident) => { stringify!($fname) };
    (@method $fname:ident = $n:expr) => { $n };

    (@add $service:ident, $Self:ty, $fname:ident) => { $service.add(stringify!($fname), <$Self as Service>::$fname); };
    (@add $service:ident, $Self:ty, $fname:ident = $n:expr) => { $service.add($n, <$Self as Service>::$fname); };

    (@serv ($m:ident, $(<$lf:lifetime>)? $(*$ss:ident,)? $($arg:ident: $type:ty),*)) => {
        async fn $m$(<$lf>)?(&$($lf)? self, $($ss: $crate::ArcRpcContext,)? $($arg: $type),*) -> ::anyhow::Result<()>;
    };
    (@serv ($m:ident, $(<$lf:lifetime>)? $(*$ss:ident,)? $($arg:ident: $type:ty),*) -> $ret:ty) => {
        async fn $m$(<$lf>)?(&$($lf)? self, $($ss: $crate::ArcRpcContext,)? $($arg: $type),*) -> ::anyhow::Result<$ret>;
    };

    (@decl ($m:ident, $(<$lf:lifetime>)? $($arg:ident: $type:ty),*)) => {
        async fn $m$(<$lf>)?(self: &$($lf)? ::std::sync::Arc<Self>, $($arg: $type),*) -> ::anyhow::Result<()>;
    };
    (@decl ($m:ident, $(<$lf:lifetime>)? $($arg:ident: $type:ty),*) -> $ret:ty) => {
        async fn $m$(<$lf>)?(self: &$($lf)? ::std::sync::Arc<Self>, $($arg: $type),*) -> ::anyhow::Result<$ret>;
    };

    (@call ($m:ident $(= $n:expr)?, $(<$lf:lifetime>)? $($arg:ident: $type:ty),*)) => {
        #[inline]
        async fn $m$(<$lf>)?(self: &$($lf)? ::std::sync::Arc<Self>, $($arg: $type),*) -> ::anyhow::Result<()> {
            self.notify($crate::ezrpc!(@method $m $(= $n)?), ($($arg),*)).await
        }
    };
    (@call ($m:ident $(= $n:expr)?, $(<$lf:lifetime>)? $($arg:ident: $type:ty),*) -> $ret:ty) => {
        #[inline]
        async fn $m$(<$lf>)?(self: &$($lf)? ::std::sync::Arc<Self>, $($arg: $type),*) -> ::anyhow::Result<$ret> {
            self.request($crate::ezrpc!(@method $m $(= $n)?), ($($arg),*)).await
        }
    };
}