builder api

This commit is contained in:
Aiden McClelland
2024-01-02 12:45:13 -07:00
parent 4cbbf1a0a7
commit bb29367e94
8 changed files with 373 additions and 405 deletions

View File

@@ -1362,7 +1362,7 @@ fn build_inherited(parent_data: Option<Type>, generics: &Generics) -> (TokenStre
) )
} else { } else {
( (
quote! { type InheritedParams = ::rpc_toolkit::NoParams; }, quote! { type InheritedParams = ::rpc_toolkit::Empty; },
inherited_generics, inherited_generics,
) )
} }

View File

@@ -3,7 +3,6 @@ use std::collections::VecDeque;
use std::fmt::Debug; use std::fmt::Debug;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::sync::Arc; use std::sync::Arc;
use std::task::Context;
use clap::{CommandFactory, FromArgMatches}; use clap::{CommandFactory, FromArgMatches};
use imbl_value::imbl::{OrdMap, OrdSet}; use imbl_value::imbl::{OrdMap, OrdSet};
@@ -14,8 +13,8 @@ use yajrc::RpcError;
use crate::util::{internal_error, parse_error, Flat}; use crate::util::{internal_error, parse_error, Flat};
use crate::{ use crate::{
intersect_type_ids, iter_from_ctx_and_handler, AnyHandler, CallRemote, CliBindings, DynHandler, iter_from_ctx_and_handler, AnyHandler, CallRemote, CliBindings, DynHandler, EitherContext,
HandleArgs, Handler, HandlerTypes, IntoContext, IntoHandlers, NoParams, PrintCliResult, HandleArgs, Handler, HandlerTypes, IntoContext, IntoHandlers, PrintCliResult,
}; };
pub trait HandlerExt: HandlerTypes + Sized { pub trait HandlerExt: HandlerTypes + Sized {
@@ -34,6 +33,13 @@ pub trait HandlerExt: HandlerTypes + Sized {
) -> CustomDisplayFn<Context, F, Self> ) -> CustomDisplayFn<Context, F, Self>
where where
F: Fn(HandleArgs<Context, Self>, Self::Ok) -> Result<(), Self::Err>; F: Fn(HandleArgs<Context, Self>, Self::Ok) -> Result<(), Self::Err>;
fn with_inherited<Params, InheritedParams, F>(
self,
f: F,
) -> InheritanceHandler<Params, InheritedParams, Self, F>
where
F: Fn(Params, InheritedParams) -> Self::InheritedParams;
fn with_remote_cli<Context>(self) -> RemoteCli<Context, Self>;
} }
impl<T: HandlerTypes + Sized> HandlerExt for T { impl<T: HandlerTypes + Sized> HandlerExt for T {
@@ -67,6 +73,25 @@ impl<T: HandlerTypes + Sized> HandlerExt for T {
handler: self, handler: self,
} }
} }
fn with_inherited<Params, InheritedParams, F>(
self,
f: F,
) -> InheritanceHandler<Params, InheritedParams, Self, F>
where
F: Fn(Params, InheritedParams) -> Self::InheritedParams,
{
InheritanceHandler {
_phantom: PhantomData,
handler: self,
inherit: f,
}
}
fn with_remote_cli<Context>(self) -> RemoteCli<Context, Self> {
RemoteCli {
_phantom: PhantomData,
handler: self,
}
}
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@@ -77,6 +102,21 @@ impl<H: HandlerTypes> HandlerTypes for NoCli<H> {
type Ok = H::Ok; type Ok = H::Ok;
type Err = H::Err; type Err = H::Err;
} }
impl<H> IntoHandlers for NoCli<H>
where
H: Handler,
H::Params: DeserializeOwned,
H::InheritedParams: DeserializeOwned,
H::Ok: Serialize + DeserializeOwned,
RpcError: From<H::Err>,
{
fn into_handlers(self) -> impl IntoIterator<Item = (Option<TypeId>, DynHandler)> {
iter_from_ctx_and_handler(
self.0.contexts(),
DynHandler::WithoutCli(Arc::new(AnyHandler::new(self.0))),
)
}
}
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct CustomDisplay<P, H> { pub struct CustomDisplay<P, H> {
@@ -171,13 +211,13 @@ where
+ 'static, + 'static,
{ {
type Context = P::Context; type Context = P::Context;
fn cli_command(&self, ctx_ty: TypeId) -> clap::Command { fn cli_command(&self, _: TypeId) -> clap::Command {
H::Params::command() H::Params::command()
} }
fn cli_parse( fn cli_parse(
&self, &self,
matches: &clap::ArgMatches, matches: &clap::ArgMatches,
ctx_ty: TypeId, _: TypeId,
) -> Result<(VecDeque<&'static str>, Value), clap::Error> { ) -> Result<(VecDeque<&'static str>, Value), clap::Error> {
Self::Params::from_arg_matches(matches).and_then(|a| { Self::Params::from_arg_matches(matches).and_then(|a| {
Ok(( Ok((
@@ -212,21 +252,6 @@ where
) )
} }
} }
impl<P, H> IntoHandlers for CustomDisplay<P, H>
where
Self: HandlerTypes + Handler + CliBindings,
<Self as HandlerTypes>::Params: DeserializeOwned,
<Self as HandlerTypes>::InheritedParams: DeserializeOwned,
<Self as HandlerTypes>::Ok: Serialize + DeserializeOwned,
RpcError: From<<Self as HandlerTypes>::Err>,
{
fn into_handlers(self) -> impl IntoIterator<Item = (Option<TypeId>, crate::DynHandler)> {
iter_from_ctx_and_handler(
intersect_type_ids(self.contexts(), <Self as CliBindings>::Context::type_ids()),
DynHandler::WithCli(Arc::new(AnyHandler::new(self))),
)
}
}
pub struct CustomDisplayFn<Context, F, H> { pub struct CustomDisplayFn<Context, F, H> {
_phantom: PhantomData<Context>, _phantom: PhantomData<Context>,
@@ -371,115 +396,282 @@ where
} }
} }
// pub struct RemoteCli<CliContext, RemoteContext, H> { pub struct RemoteCli<Context, H> {
// _phantom: PhantomData<(CliContext, RemoteContext)>, _phantom: PhantomData<Context>,
// handler: H, handler: H,
// } }
// impl<CliContext, RemoteContext, H: Clone> Clone for RemoteCli<CliContext, RemoteContext, H> { impl<Context, H: Clone> Clone for RemoteCli<Context, H> {
// fn clone(&self) -> Self { fn clone(&self) -> Self {
// Self { Self {
// _phantom: PhantomData, _phantom: PhantomData,
// handler: self.handler.clone(), handler: self.handler.clone(),
// } }
// } }
// } }
// impl<CliContext, RemoteContext, H: Debug> Debug for RemoteCli<CliContext, RemoteContext, H> { impl<Context, H: Debug> Debug for RemoteCli<Context, H> {
// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// f.debug_tuple("RemoteCli").field(&self.handler).finish() f.debug_tuple("RemoteCli").field(&self.handler).finish()
// } }
// } }
// impl<CliContext, RemoteContext, H> HandlerTypes for RemoteCli<CliContext, RemoteContext, H> impl<Context, H> HandlerTypes for RemoteCli<Context, H>
// where where
// H: HandlerTypes, H: HandlerTypes,
// { {
// type Params = H::Params; type Params = H::Params;
// type InheritedParams = H::InheritedParams; type InheritedParams = H::InheritedParams;
// type Ok = H::Ok; type Ok = H::Ok;
// type Err = H::Err; type Err = H::Err;
// } }
// #[async_trait::async_trait] #[async_trait::async_trait]
// impl<CliContext, RemoteContext, H> Handler<EitherContext<CliContext, RemoteContext>> impl<Context, H> Handler for RemoteCli<Context, H>
// for RemoteCli<CliContext, RemoteContext, H> where
// where Context: CallRemote,
// CliContext: CallRemote, H: Handler,
// H: Handler<RemoteContext>, H::Params: Serialize,
// { H::InheritedParams: Serialize,
// async fn handle_async( H::Ok: DeserializeOwned,
// &self, H::Err: From<RpcError>,
// HandleArgs { {
// context, type Context = EitherContext<Context, H::Context>;
// parent_method, async fn handle_async(
// method, &self,
// params, HandleArgs {
// inherited_params, context,
// raw_params, parent_method,
// }: HandleArgs<CliContext, Self>, method,
// ) -> Result<Self::Ok, Self::Err> { params,
// let full_method = parent_method.into_iter().chain(method).collect::<Vec<_>>(); inherited_params,
// match context raw_params,
// .call_remote( }: HandleArgs<Self::Context, Self>,
// &full_method.join("."), ) -> Result<Self::Ok, Self::Err> {
// imbl_value::to_value(&Flat(params, inherited_params)).map_err(parse_error)?, match context {
// ) EitherContext::C1(context) => {
// .await let full_method = parent_method.into_iter().chain(method).collect::<Vec<_>>();
// { match context
// Ok(a) => imbl_value::from_value(a) .call_remote(
// .map_err(internal_error) &full_method.join("."),
// .map_err(Self::Err::from), imbl_value::to_value(&Flat(params, inherited_params))
// Err(e) => Err(Self::Err::from(e)), .map_err(parse_error)?,
// } )
// } .await
// fn metadata( {
// &self, Ok(a) => imbl_value::from_value(a)
// method: VecDeque<&'static str>, .map_err(internal_error)
// ctx_ty: TypeId, .map_err(Self::Err::from),
// ) -> OrdMap<&'static str, Value> { Err(e) => Err(Self::Err::from(e)),
// self.handler.metadata(method, ctx_ty) }
// } }
// fn contexts(&self) -> Option<OrdSet<TypeId>> { EitherContext::C2(context) => {
// todo!() self.handler
// } .handle_async(HandleArgs {
// fn method_from_dots(&self, method: &str, ctx_ty: TypeId) -> Option<VecDeque<&'static str>> { context,
// self.handler.method_from_dots(method, ctx_ty) parent_method,
// } method,
// } params,
// impl<Context, H> CliBindings<Context> for RemoteCli<Context, H> inherited_params,
// where raw_params,
// Context: crate::Context, })
// H: CliBindings<Context>, .await
// { }
// fn cli_command(&self, ctx_ty: TypeId) -> clap::Command { }
// self.handler.cli_command(ctx_ty) }
// } fn metadata(
// fn cli_parse( &self,
// &self, method: VecDeque<&'static str>,
// matches: &clap::ArgMatches, ctx_ty: TypeId,
// ctx_ty: TypeId, ) -> OrdMap<&'static str, Value> {
// ) -> Result<(VecDeque<&'static str>, Value), clap::Error> { self.handler.metadata(method, ctx_ty)
// self.handler.cli_parse(matches, ctx_ty) }
// } fn contexts(&self) -> Option<OrdSet<TypeId>> {
// fn cli_display( todo!()
// &self, }
// HandleArgs { fn method_from_dots(&self, method: &str, ctx_ty: TypeId) -> Option<VecDeque<&'static str>> {
// context, self.handler.method_from_dots(method, ctx_ty)
// parent_method, }
// method, }
// params, impl<Context, H> CliBindings for RemoteCli<Context, H>
// inherited_params, where
// raw_params, H: CliBindings,
// }: HandleArgs<Context, Self>, {
// result: Self::Ok, type Context = H::Context;
// ) -> Result<(), Self::Err> { fn cli_command(&self, ctx_ty: TypeId) -> clap::Command {
// self.handler.cli_display( self.handler.cli_command(ctx_ty)
// HandleArgs { }
// context, fn cli_parse(
// parent_method, &self,
// method, matches: &clap::ArgMatches,
// params, ctx_ty: TypeId,
// inherited_params, ) -> Result<(VecDeque<&'static str>, Value), clap::Error> {
// raw_params, self.handler.cli_parse(matches, ctx_ty)
// }, }
// result, fn cli_display(
// ) &self,
// } HandleArgs {
// } context,
parent_method,
method,
params,
inherited_params,
raw_params,
}: HandleArgs<Self::Context, Self>,
result: Self::Ok,
) -> Result<(), Self::Err> {
self.handler.cli_display(
HandleArgs {
context,
parent_method,
method,
params,
inherited_params,
raw_params,
},
result,
)
}
}
pub struct InheritanceHandler<Params, InheritedParams, H, F> {
_phantom: PhantomData<(Params, InheritedParams)>,
handler: H,
inherit: F,
}
impl<Params, InheritedParams, H: Clone, F: Clone> Clone
for InheritanceHandler<Params, InheritedParams, H, F>
{
fn clone(&self) -> Self {
Self {
_phantom: PhantomData,
handler: self.handler.clone(),
inherit: self.inherit.clone(),
}
}
}
impl<Params, InheritedParams, H: std::fmt::Debug, F> std::fmt::Debug
for InheritanceHandler<Params, InheritedParams, H, F>
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("InheritanceHandler")
.field(&self.handler)
.finish()
}
}
impl<Params, InheritedParams, H, F> HandlerTypes
for InheritanceHandler<Params, InheritedParams, H, F>
where
H: HandlerTypes,
Params: Send + Sync,
InheritedParams: Send + Sync,
{
type Params = H::Params;
type InheritedParams = Flat<Params, InheritedParams>;
type Ok = H::Ok;
type Err = H::Err;
}
#[async_trait::async_trait]
impl<Params, InheritedParams, H, F> Handler for InheritanceHandler<Params, InheritedParams, H, F>
where
Params: Send + Sync + 'static,
InheritedParams: Send + Sync + 'static,
H: Handler,
F: Fn(Params, InheritedParams) -> H::InheritedParams + Send + Sync + Clone + 'static,
{
type Context = H::Context;
fn handle_sync(
&self,
HandleArgs {
context,
parent_method,
method,
params,
inherited_params,
raw_params,
}: HandleArgs<Self::Context, Self>,
) -> Result<Self::Ok, Self::Err> {
self.handler.handle_sync(HandleArgs {
context,
parent_method,
method,
params,
inherited_params: (self.inherit)(inherited_params.0, inherited_params.1),
raw_params,
})
}
async fn handle_async(
&self,
HandleArgs {
context,
parent_method,
method,
params,
inherited_params,
raw_params,
}: HandleArgs<Self::Context, Self>,
) -> Result<Self::Ok, Self::Err> {
self.handler.handle_sync(HandleArgs {
context,
parent_method,
method,
params,
inherited_params: (self.inherit)(inherited_params.0, inherited_params.1),
raw_params,
})
}
fn metadata(
&self,
method: VecDeque<&'static str>,
ctx_ty: TypeId,
) -> OrdMap<&'static str, Value> {
self.handler.metadata(method, ctx_ty)
}
fn contexts(&self) -> Option<OrdSet<TypeId>> {
self.handler.contexts()
}
fn method_from_dots(&self, method: &str, ctx_ty: TypeId) -> Option<VecDeque<&'static str>> {
self.handler.method_from_dots(method, ctx_ty)
}
}
impl<Params, InheritedParams, H, F> CliBindings
for InheritanceHandler<Params, InheritedParams, H, F>
where
Params: Send + Sync + 'static,
InheritedParams: Send + Sync + 'static,
H: CliBindings,
F: Fn(Params, InheritedParams) -> H::InheritedParams + Send + Sync + Clone + 'static,
{
type Context = H::Context;
fn cli_command(&self, ctx_ty: TypeId) -> clap::Command {
self.handler.cli_command(ctx_ty)
}
fn cli_parse(
&self,
matches: &clap::ArgMatches,
ctx_ty: TypeId,
) -> Result<(VecDeque<&'static str>, Value), clap::Error> {
self.handler.cli_parse(matches, ctx_ty)
}
fn cli_display(
&self,
HandleArgs {
context,
parent_method,
method,
params,
inherited_params,
raw_params,
}: HandleArgs<Self::Context, Self>,
result: Self::Ok,
) -> Result<(), Self::Err> {
self.handler.cli_display(
HandleArgs {
context,
parent_method,
method,
params,
inherited_params: (self.inherit)(inherited_params.0, inherited_params.1),
raw_params,
},
result,
)
}
}

View File

@@ -2,7 +2,6 @@ use std::any::TypeId;
use std::collections::VecDeque; use std::collections::VecDeque;
use std::fmt::Display; use std::fmt::Display;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::sync::Arc;
use clap::{ArgMatches, Command, CommandFactory, FromArgMatches}; use clap::{ArgMatches, Command, CommandFactory, FromArgMatches};
use futures::Future; use futures::Future;
@@ -10,12 +9,10 @@ use imbl_value::imbl::OrdMap;
use imbl_value::Value; use imbl_value::Value;
use serde::de::DeserializeOwned; use serde::de::DeserializeOwned;
use serde::Serialize; use serde::Serialize;
use yajrc::RpcError;
use crate::marker::LeafHandler; use crate::marker::LeafHandler;
use crate::{ use crate::{
intersect_type_ids, iter_from_ctx_and_handler, AnyContext, AnyHandler, CliBindings, DynHandler, AnyContext, CliBindings, Empty, HandleArgs, Handler, HandlerTypes, IntoContext, PrintCliResult,
HandleArgs, Handler, HandlerTypes, IntoContext, IntoHandlers, NoCli, NoParams, PrintCliResult,
}; };
pub struct FromFn<F, T, E, Args> { pub struct FromFn<F, T, E, Args> {
@@ -58,36 +55,6 @@ where
Ok(println!("{result}")) Ok(println!("{result}"))
} }
} }
impl<F, T, E, Args> IntoHandlers for FromFn<F, T, E, Args>
where
Self: HandlerTypes + Handler + CliBindings,
<Self as HandlerTypes>::Params: DeserializeOwned,
<Self as HandlerTypes>::InheritedParams: DeserializeOwned,
<Self as HandlerTypes>::Ok: Serialize + DeserializeOwned,
RpcError: From<<Self as HandlerTypes>::Err>,
{
fn into_handlers(self) -> impl IntoIterator<Item = (Option<TypeId>, crate::DynHandler)> {
iter_from_ctx_and_handler(
intersect_type_ids(self.contexts(), <Self as CliBindings>::Context::type_ids()),
DynHandler::WithCli(Arc::new(AnyHandler::new(self))),
)
}
}
impl<F, T, E, Args> IntoHandlers for NoCli<FromFn<F, T, E, Args>>
where
Self: HandlerTypes + Handler,
<Self as HandlerTypes>::Params: DeserializeOwned,
<Self as HandlerTypes>::InheritedParams: DeserializeOwned,
<Self as HandlerTypes>::Ok: Serialize + DeserializeOwned,
RpcError: From<<Self as HandlerTypes>::Err>,
{
fn into_handlers(self) -> impl IntoIterator<Item = (Option<TypeId>, crate::DynHandler)> {
iter_from_ctx_and_handler(
self.contexts(),
DynHandler::WithoutCli(Arc::new(AnyHandler::new(self))),
)
}
}
pub fn from_fn<F, T, E, Args>(function: F) -> FromFn<F, T, E, Args> { pub fn from_fn<F, T, E, Args>(function: F) -> FromFn<F, T, E, Args> {
FromFn { FromFn {
@@ -136,36 +103,6 @@ where
Ok(println!("{result}")) Ok(println!("{result}"))
} }
} }
impl<F, Fut, T, E, Args> IntoHandlers for FromFnAsync<F, Fut, T, E, Args>
where
Self: HandlerTypes + Handler + CliBindings,
<Self as HandlerTypes>::Params: DeserializeOwned,
<Self as HandlerTypes>::InheritedParams: DeserializeOwned,
<Self as HandlerTypes>::Ok: Serialize + DeserializeOwned,
RpcError: From<<Self as HandlerTypes>::Err>,
{
fn into_handlers(self) -> impl IntoIterator<Item = (Option<TypeId>, crate::DynHandler)> {
iter_from_ctx_and_handler(
intersect_type_ids(self.contexts(), <Self as CliBindings>::Context::type_ids()),
DynHandler::WithCli(Arc::new(AnyHandler::new(self))),
)
}
}
impl<F, Fut, T, E, Args> IntoHandlers for NoCli<FromFnAsync<F, Fut, T, E, Args>>
where
Self: HandlerTypes + Handler,
<Self as HandlerTypes>::Params: DeserializeOwned,
<Self as HandlerTypes>::InheritedParams: DeserializeOwned,
<Self as HandlerTypes>::Ok: Serialize + DeserializeOwned,
RpcError: From<<Self as HandlerTypes>::Err>,
{
fn into_handlers(self) -> impl IntoIterator<Item = (Option<TypeId>, crate::DynHandler)> {
iter_from_ctx_and_handler(
self.contexts(),
DynHandler::WithoutCli(Arc::new(AnyHandler::new(self))),
)
}
}
pub fn from_fn_async<F, Fut, T, E, Args>(function: F) -> FromFnAsync<F, Fut, T, E, Args> { pub fn from_fn_async<F, Fut, T, E, Args>(function: F) -> FromFnAsync<F, Fut, T, E, Args> {
FromFnAsync { FromFnAsync {
@@ -181,8 +118,8 @@ where
T: Send + Sync + 'static, T: Send + Sync + 'static,
E: Send + Sync + 'static, E: Send + Sync + 'static,
{ {
type Params = NoParams; type Params = Empty;
type InheritedParams = NoParams; type InheritedParams = Empty;
type Ok = T; type Ok = T;
type Err = E; type Err = E;
} }
@@ -218,8 +155,8 @@ where
T: Send + Sync + 'static, T: Send + Sync + 'static,
E: Send + Sync + 'static, E: Send + Sync + 'static,
{ {
type Params = NoParams; type Params = Empty;
type InheritedParams = NoParams; type InheritedParams = Empty;
type Ok = T; type Ok = T;
type Err = E; type Err = E;
} }
@@ -250,8 +187,8 @@ where
T: Send + Sync + 'static, T: Send + Sync + 'static,
E: Send + Sync + 'static, E: Send + Sync + 'static,
{ {
type Params = NoParams; type Params = Empty;
type InheritedParams = NoParams; type InheritedParams = Empty;
type Ok = T; type Ok = T;
type Err = E; type Err = E;
} }
@@ -292,8 +229,8 @@ where
T: Send + Sync + 'static, T: Send + Sync + 'static,
E: Send + Sync + 'static, E: Send + Sync + 'static,
{ {
type Params = NoParams; type Params = Empty;
type InheritedParams = NoParams; type InheritedParams = Empty;
type Ok = T; type Ok = T;
type Err = E; type Err = E;
} }
@@ -327,7 +264,7 @@ where
E: Send + Sync + 'static, E: Send + Sync + 'static,
{ {
type Params = Params; type Params = Params;
type InheritedParams = NoParams; type InheritedParams = Empty;
type Ok = T; type Ok = T;
type Err = E; type Err = E;
} }
@@ -374,7 +311,7 @@ where
E: Send + Sync + 'static, E: Send + Sync + 'static,
{ {
type Params = Params; type Params = Params;
type InheritedParams = NoParams; type InheritedParams = Empty;
type Ok = T; type Ok = T;
type Err = E; type Err = E;
} }

View File

@@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize};
use yajrc::RpcError; use yajrc::RpcError;
use crate::context::{AnyContext, IntoContext}; use crate::context::{AnyContext, IntoContext};
use crate::util::{internal_error, invalid_params}; use crate::util::{internal_error, invalid_params, Flat};
pub mod adapters; pub mod adapters;
pub mod from_fn; pub mod from_fn;
@@ -311,7 +311,11 @@ where
} }
#[derive(Debug, Clone, Copy, Deserialize, Serialize, Parser)] #[derive(Debug, Clone, Copy, Deserialize, Serialize, Parser)]
pub struct NoParams {} pub struct Empty {}
pub(crate) trait OrEmpty<T> {}
impl<T> OrEmpty<T> for T {}
impl<A, B> OrEmpty<Flat<A, B>> for Empty {}
#[derive(Debug, Clone, Copy, Deserialize, Serialize, Parser)] #[derive(Debug, Clone, Copy, Deserialize, Serialize, Parser)]
pub enum Never {} pub enum Never {}

View File

@@ -12,15 +12,22 @@ use yajrc::RpcError;
use crate::util::{combine, Flat}; use crate::util::{combine, Flat};
use crate::{ use crate::{
AnyContext, AnyHandler, CliBindings, DynHandler, HandleAny, HandleAnyArgs, HandleArgs, Handler, AnyContext, AnyHandler, CliBindings, DynHandler, Empty, HandleAny, HandleAnyArgs, HandleArgs,
HandlerTypes, IntoContext, NoCli, NoParams, Handler, HandlerTypes, IntoContext, OrEmpty,
}; };
pub trait IntoHandlers: HandlerTypes { pub trait IntoHandlers: HandlerTypes {
fn into_handlers(self) -> impl IntoIterator<Item = (Option<TypeId>, DynHandler)>; fn into_handlers(self) -> impl IntoIterator<Item = (Option<TypeId>, DynHandler)>;
} }
impl<H: Handler + CliBindings> IntoHandlers for H { impl<H> IntoHandlers for H
where
H: Handler + CliBindings,
H::Params: DeserializeOwned,
H::InheritedParams: DeserializeOwned,
H::Ok: Serialize + DeserializeOwned,
RpcError: From<H::Err>,
{
fn into_handlers(self) -> impl IntoIterator<Item = (Option<TypeId>, DynHandler)> { fn into_handlers(self) -> impl IntoIterator<Item = (Option<TypeId>, DynHandler)> {
iter_from_ctx_and_handler( iter_from_ctx_and_handler(
intersect_type_ids(self.contexts(), <Self as CliBindings>::Context::type_ids()), intersect_type_ids(self.contexts(), <Self as CliBindings>::Context::type_ids()),
@@ -89,7 +96,7 @@ impl SubcommandMap {
} }
} }
pub struct ParentHandler<Params = NoParams, InheritedParams = NoParams> { pub struct ParentHandler<Params = Empty, InheritedParams = Empty> {
_phantom: PhantomData<(Params, InheritedParams)>, _phantom: PhantomData<(Params, InheritedParams)>,
pub(crate) subcommands: SubcommandMap, pub(crate) subcommands: SubcommandMap,
metadata: OrdMap<&'static str, Value>, metadata: OrdMap<&'static str, Value>,
@@ -124,152 +131,6 @@ impl<Params, InheritedParams> std::fmt::Debug for ParentHandler<Params, Inherite
} }
} }
struct InheritanceHandler<Params, InheritedParams, H, F> {
_phantom: PhantomData<(Params, InheritedParams)>,
handler: H,
inherit: F,
}
impl<Params, InheritedParams, H: Clone, F: Clone> Clone
for InheritanceHandler<Params, InheritedParams, H, F>
{
fn clone(&self) -> Self {
Self {
_phantom: PhantomData,
handler: self.handler.clone(),
inherit: self.inherit.clone(),
}
}
}
impl<Params, InheritedParams, H: std::fmt::Debug, F> std::fmt::Debug
for InheritanceHandler<Params, InheritedParams, H, F>
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("InheritanceHandler")
.field(&self.handler)
.finish()
}
}
impl<Params, InheritedParams, H, F> HandlerTypes
for InheritanceHandler<Params, InheritedParams, H, F>
where
H: HandlerTypes,
Params: Send + Sync,
InheritedParams: Send + Sync,
{
type Params = H::Params;
type InheritedParams = Flat<Params, InheritedParams>;
type Ok = H::Ok;
type Err = H::Err;
}
#[async_trait::async_trait]
impl<Params, InheritedParams, H, F> Handler for InheritanceHandler<Params, InheritedParams, H, F>
where
Params: Send + Sync + 'static,
InheritedParams: Send + Sync + 'static,
H: Handler,
F: Fn(Params, InheritedParams) -> H::InheritedParams + Send + Sync + Clone + 'static,
{
type Context = H::Context;
fn handle_sync(
&self,
HandleArgs {
context,
parent_method,
method,
params,
inherited_params,
raw_params,
}: HandleArgs<Self::Context, Self>,
) -> Result<Self::Ok, Self::Err> {
self.handler.handle_sync(HandleArgs {
context,
parent_method,
method,
params,
inherited_params: (self.inherit)(inherited_params.0, inherited_params.1),
raw_params,
})
}
async fn handle_async(
&self,
HandleArgs {
context,
parent_method,
method,
params,
inherited_params,
raw_params,
}: HandleArgs<Self::Context, Self>,
) -> Result<Self::Ok, Self::Err> {
self.handler.handle_sync(HandleArgs {
context,
parent_method,
method,
params,
inherited_params: (self.inherit)(inherited_params.0, inherited_params.1),
raw_params,
})
}
fn metadata(
&self,
method: VecDeque<&'static str>,
ctx_ty: TypeId,
) -> OrdMap<&'static str, Value> {
self.handler.metadata(method, ctx_ty)
}
fn contexts(&self) -> Option<OrdSet<TypeId>> {
self.handler.contexts()
}
fn method_from_dots(&self, method: &str, ctx_ty: TypeId) -> Option<VecDeque<&'static str>> {
self.handler.method_from_dots(method, ctx_ty)
}
}
impl<Params, InheritedParams, H, F> CliBindings
for InheritanceHandler<Params, InheritedParams, H, F>
where
Params: Send + Sync + 'static,
InheritedParams: Send + Sync + 'static,
H: CliBindings,
F: Fn(Params, InheritedParams) -> H::InheritedParams + Send + Sync + Clone + 'static,
{
type Context = H::Context;
fn cli_command(&self, ctx_ty: TypeId) -> Command {
self.handler.cli_command(ctx_ty)
}
fn cli_parse(
&self,
matches: &ArgMatches,
ctx_ty: TypeId,
) -> Result<(VecDeque<&'static str>, Value), clap::Error> {
self.handler.cli_parse(matches, ctx_ty)
}
fn cli_display(
&self,
HandleArgs {
context,
parent_method,
method,
params,
inherited_params,
raw_params,
}: HandleArgs<Self::Context, Self>,
result: Self::Ok,
) -> Result<(), Self::Err> {
self.handler.cli_display(
HandleArgs {
context,
parent_method,
method,
params,
inherited_params: (self.inherit)(inherited_params.0, inherited_params.1),
raw_params,
},
result,
)
}
}
impl<Params, InheritedParams> ParentHandler<Params, InheritedParams> { impl<Params, InheritedParams> ParentHandler<Params, InheritedParams> {
fn get_contexts(&self) -> Option<OrdSet<TypeId>> { fn get_contexts(&self) -> Option<OrdSet<TypeId>> {
let mut set = OrdSet::new(); let mut set = OrdSet::new();
@@ -278,17 +139,21 @@ impl<Params, InheritedParams> ParentHandler<Params, InheritedParams> {
} }
Some(set) Some(set)
} }
#[allow(private_bounds)]
pub fn subcommand<H>(mut self, name: &'static str, handler: H) -> Self pub fn subcommand<H>(mut self, name: &'static str, handler: H) -> Self
where where
H: IntoHandlers<InheritedParams = Flat<Params, InheritedParams>>, H: IntoHandlers,
H::InheritedParams: OrEmpty<Flat<Params, InheritedParams>>,
{ {
self.subcommands self.subcommands
.insert(name.into(), handler.into_handlers()); .insert(name.into(), handler.into_handlers());
self self
} }
#[allow(private_bounds)]
pub fn root_handler<H>(mut self, handler: H) -> Self pub fn root_handler<H>(mut self, handler: H) -> Self
where where
H: IntoHandlers<Params = NoParams, InheritedParams = Flat<Params, InheritedParams>>, H: IntoHandlers<Params = Empty>,
H::InheritedParams: OrEmpty<Flat<Params, InheritedParams>>,
{ {
self.subcommands.insert(None, handler.into_handlers()); self.subcommands.insert(None, handler.into_handlers());
self self
@@ -488,33 +353,3 @@ where
} }
} }
} }
impl<Params, InheritedParams> IntoHandlers for ParentHandler<Params, InheritedParams>
where
Self: HandlerTypes + Handler + CliBindings,
<Self as HandlerTypes>::Params: DeserializeOwned,
<Self as HandlerTypes>::InheritedParams: DeserializeOwned,
<Self as HandlerTypes>::Ok: Serialize + DeserializeOwned,
RpcError: From<<Self as HandlerTypes>::Err>,
{
fn into_handlers(self) -> impl IntoIterator<Item = (Option<TypeId>, DynHandler)> {
iter_from_ctx_and_handler(
self.contexts(),
DynHandler::WithoutCli(Arc::new(AnyHandler::new(self))),
)
}
}
impl<Params, InheritedParams> IntoHandlers for NoCli<ParentHandler<Params, InheritedParams>>
where
ParentHandler<Params, InheritedParams>: HandlerTypes + Handler,
<ParentHandler<Params, InheritedParams> as HandlerTypes>::Params: DeserializeOwned,
<ParentHandler<Params, InheritedParams> as HandlerTypes>::InheritedParams: DeserializeOwned,
<ParentHandler<Params, InheritedParams> as HandlerTypes>::Ok: Serialize + DeserializeOwned,
RpcError: From<<ParentHandler<Params, InheritedParams> as HandlerTypes>::Err>,
{
fn into_handlers(self) -> impl IntoIterator<Item = (Option<TypeId>, DynHandler)> {
iter_from_ctx_and_handler(
self.0.contexts(),
DynHandler::WithoutCli(Arc::new(AnyHandler::new(self.0))),
)
}
}

View File

@@ -1,10 +1,8 @@
use std::any::TypeId; use std::any::TypeId;
use std::task::Context;
use futures::future::{join_all, BoxFuture}; use futures::future::{join_all, BoxFuture};
use futures::FutureExt; use futures::FutureExt;
use http::header::{CONTENT_LENGTH, CONTENT_TYPE}; use http::header::{CONTENT_LENGTH, CONTENT_TYPE};
use http::request::Parts;
use http_body_util::BodyExt; use http_body_util::BodyExt;
use hyper::body::{Bytes, Incoming}; use hyper::body::{Bytes, Incoming};
use hyper::service::Service; use hyper::service::Service;
@@ -16,7 +14,7 @@ use yajrc::{RpcError, RpcMethod};
use crate::server::{RpcRequest, RpcResponse, SingleOrBatchRpcRequest}; use crate::server::{RpcRequest, RpcResponse, SingleOrBatchRpcRequest};
use crate::util::{internal_error, parse_error}; use crate::util::{internal_error, parse_error};
use crate::{handler, HandleAny, Server}; use crate::{HandleAny, Server};
const FALLBACK_ERROR: &str = "{\"error\":{\"code\":-32603,\"message\":\"Internal error\",\"data\":\"Failed to serialize rpc response\"}}"; const FALLBACK_ERROR: &str = "{\"error\":{\"code\":-32603,\"message\":\"Internal error\",\"data\":\"Failed to serialize rpc response\"}}";

View File

@@ -8,7 +8,7 @@ use imbl_value::Value;
use yajrc::{RpcError, RpcMethod}; use yajrc::{RpcError, RpcMethod};
use crate::util::{invalid_request, JobRunner}; use crate::util::{invalid_request, JobRunner};
use crate::{AnyContext, AnyHandler, HandleAny, HandleAnyArgs, IntoContext, ParentHandler}; use crate::{AnyHandler, HandleAny, HandleAnyArgs, IntoContext, ParentHandler};
type GenericRpcMethod = yajrc::GenericRpcMethod<String, Value, Value>; type GenericRpcMethod = yajrc::GenericRpcMethod<String, Value, Value>;
type RpcRequest = yajrc::RpcRequest<GenericRpcMethod>; type RpcRequest = yajrc::RpcRequest<GenericRpcMethod>;

View File

@@ -8,8 +8,8 @@ use clap::Parser;
use futures::future::ready; use futures::future::ready;
use imbl_value::Value; use imbl_value::Value;
use rpc_toolkit::{ use rpc_toolkit::{
call_remote_socket, from_fn, from_fn_async, AnyContext, CallRemote, CliApp, Context, NoParams, call_remote_socket, from_fn, from_fn_async, AnyContext, CallRemote, CliApp, Context, Empty,
ParentHandler, Server, HandlerExt, ParentHandler, Server,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tokio::runtime::{Handle, Runtime}; use tokio::runtime::{Handle, Runtime};
@@ -141,7 +141,7 @@ fn make_api() -> ParentHandler {
.subcommand("a_hello", from_fn_async(a_hello)) .subcommand("a_hello", from_fn_async(a_hello))
.subcommand( .subcommand(
"dondes", "dondes",
ParentHandler::<InheritParams>::new().subcommand_with_inherited_no_cli( ParentHandler::<InheritParams>::new().subcommand(
"donde", "donde",
from_fn(|c: CliContext, _: (), donde| { from_fn(|c: CliContext, _: (), donde| {
Ok::<_, RpcError>( Ok::<_, RpcError>(
@@ -151,8 +151,9 @@ fn make_api() -> ParentHandler {
) )
.to_string(), .to_string(),
) )
}), })
|InheritParams { donde }, _| donde, .with_inherited(|InheritParams { donde }, _| donde)
.no_cli(),
), ),
) )
.subcommand( .subcommand(
@@ -166,21 +167,22 @@ fn make_api() -> ParentHandler {
) )
.to_string(), .to_string(),
) )
}), })
|id, _| id, .with_inherited(|a, _| a),
), ),
) )
.subcommand( .subcommand(
"error", "error",
ParentHandler::<InheritParams>::new().root_handler_no_cli( ParentHandler::<InheritParams>::new().root_handler(
from_fn(|c: CliContext, _, InheritParams { donde }| { from_fn(|c: CliContext, _, InheritParams { donde }| {
Err::<String, _>(RpcError { Err::<String, _>(RpcError {
code: 1, code: 1,
message: "This is an example message".into(), message: "This is an example message".into(),
data: None, data: None,
}) })
}), })
|id, _| id, .with_inherited(|a, _| a)
.no_cli(),
), ),
) )
} }