use alux_ext::{ApplyAlg, ext};
use trait_set::trait_set;
pub trait JsonRpcAlg {
type Methods;
fn jsonrpc_empty(&self) -> Self::Methods;
fn jsonrpc_merge(&self, left: Self::Methods, right: Self::Methods) -> Self::Methods;
}
pub trait JsonRpcMethodAlg<Context, Args, Output> {
fn finish_jsonrpc_positional_method<Handler>(
&self,
name: &'static str,
arg_names: &'static [&'static str],
handler: Handler,
) -> Self::Methods
where
Self: JsonRpcAlg,
Handler: ApplyAlg<Context, Args, Output = Output> + Send + Sync + 'static;
fn finish_jsonrpc_named_method<Handler>(
&self,
name: &'static str,
arg_names: &'static [&'static str],
handler: Handler,
) -> Self::Methods
where
Self: JsonRpcAlg,
Handler: ApplyAlg<Context, Args, Output = Output> + Send + Sync + 'static;
}
pub trait OutcomeAlg {
type Value;
type Error;
fn outcome(self) -> Result<Self::Value, Self::Error>;
}
impl<Value, Error> OutcomeAlg for Result<Value, Error> {
type Value = Value;
type Error = Error;
fn outcome(self) -> Self {
self
}
}
pub trait RpcErrorAlg {
fn rpc_code(&self) -> i32;
fn rpc_message(&self) -> String;
}
impl RpcErrorAlg for core::convert::Infallible {
fn rpc_code(&self) -> i32 {
match *self {}
}
fn rpc_message(&self) -> String {
match *self {}
}
}
pub trait JsonRpcFallibleAlg<Context, Args, Output> {
fn finish_jsonrpc_positional_fallible<Handler>(
&self,
name: &'static str,
arg_names: &'static [&'static str],
handler: Handler,
) -> Self::Methods
where
Self: JsonRpcAlg,
Handler: ApplyAlg<Context, Args, Output = Output> + Send + Sync + 'static;
fn finish_jsonrpc_named_fallible<Handler>(
&self,
name: &'static str,
arg_names: &'static [&'static str],
handler: Handler,
) -> Self::Methods
where
Self: JsonRpcAlg,
Handler: ApplyAlg<Context, Args, Output = Output> + Send + Sync + 'static;
}
pub trait JsonRpcProgramAlg<Compiler> {
type Methods;
fn compile_jsonrpc(self, compiler: &Compiler) -> Self::Methods;
}
trait_set! {
pub trait JsonRpcApiAlg = JsonRpcAlg;
}
#[ext(name = JsonRpcProgramExt)]
pub impl<This> This {
fn compile_jsonrpc<Program>(&self, program: Program) -> Program::Methods
where
Program: JsonRpcProgramAlg<This>,
{
program.compile_jsonrpc(self)
}
}
#[cfg(test)]
mod tests {
use super::RpcErrorAlg;
use core::convert::Infallible;
#[test]
fn an_error_that_cannot_be_constructed_states_the_conversion() {
fn converts<Error: RpcErrorAlg>() {}
converts::<Infallible>();
}
}