mirror of
https://github.com/Start9Labs/rpc-toolkit.git
synced 2026-03-26 02:11:56 +00:00
no dynamic context
This commit is contained in:
82
src/cli.rs
82
src/cli.rs
@@ -1,4 +1,3 @@
|
|||||||
use std::any::TypeId;
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
|
|
||||||
@@ -15,8 +14,8 @@ use yajrc::{Id, RpcError};
|
|||||||
|
|
||||||
use crate::util::{internal_error, invalid_params, parse_error, without, Flat, PhantomData};
|
use crate::util::{internal_error, invalid_params, parse_error, without, Flat, PhantomData};
|
||||||
use crate::{
|
use crate::{
|
||||||
AnyHandler, CliBindingsAny, Empty, HandleAny, HandleAnyArgs, Handler, HandlerArgs,
|
AnyHandler, CliBindings, CliBindingsAny, Empty, HandleAny, HandleAnyArgs, HandlerArgs,
|
||||||
HandlerArgsFor, HandlerTypes, IntoContext, Name, ParentHandler, PrintCliResult,
|
HandlerArgsFor, HandlerFor, HandlerTypes, Name, ParentHandler, PrintCliResult,
|
||||||
};
|
};
|
||||||
|
|
||||||
type GenericRpcMethod<'a> = yajrc::GenericRpcMethod<&'a str, Value, Value>;
|
type GenericRpcMethod<'a> = yajrc::GenericRpcMethod<&'a str, Value, Value>;
|
||||||
@@ -26,14 +25,14 @@ type RpcResponse<'a> = yajrc::RpcResponse<GenericRpcMethod<'static>>;
|
|||||||
pub struct CliApp<Context: crate::Context + Clone, Config: CommandFactory + FromArgMatches> {
|
pub struct CliApp<Context: crate::Context + Clone, Config: CommandFactory + FromArgMatches> {
|
||||||
_phantom: PhantomData<(Context, Config)>,
|
_phantom: PhantomData<(Context, Config)>,
|
||||||
make_ctx: Box<dyn FnOnce(Config) -> Result<Context, RpcError> + Send + Sync>,
|
make_ctx: Box<dyn FnOnce(Config) -> Result<Context, RpcError> + Send + Sync>,
|
||||||
root_handler: ParentHandler,
|
root_handler: ParentHandler<Context>,
|
||||||
}
|
}
|
||||||
impl<Context: crate::Context + Clone, Config: CommandFactory + FromArgMatches>
|
impl<Context: crate::Context + Clone, Config: CommandFactory + FromArgMatches>
|
||||||
CliApp<Context, Config>
|
CliApp<Context, Config>
|
||||||
{
|
{
|
||||||
pub fn new<MakeCtx: FnOnce(Config) -> Result<Context, RpcError> + Send + Sync + 'static>(
|
pub fn new<MakeCtx: FnOnce(Config) -> Result<Context, RpcError> + Send + Sync + 'static>(
|
||||||
make_ctx: MakeCtx,
|
make_ctx: MakeCtx,
|
||||||
root_handler: ParentHandler,
|
root_handler: ParentHandler<Context>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
_phantom: PhantomData::new(),
|
_phantom: PhantomData::new(),
|
||||||
@@ -42,29 +41,19 @@ impl<Context: crate::Context + Clone, Config: CommandFactory + FromArgMatches>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn run(self, args: impl IntoIterator<Item = OsString>) -> Result<(), RpcError> {
|
pub fn run(self, args: impl IntoIterator<Item = OsString>) -> Result<(), RpcError> {
|
||||||
let ctx_ty = TypeId::of::<Context>();
|
|
||||||
let mut cmd = Config::command();
|
let mut cmd = Config::command();
|
||||||
for (name, handlers) in &self.root_handler.subcommands.0 {
|
for (name, handler) in &self.root_handler.subcommands.0 {
|
||||||
if let (Name(Some(name)), Some(cli)) = (
|
if let (Name(Some(name)), Some(cli)) = (name, handler.cli()) {
|
||||||
name,
|
cmd = cmd.subcommand(cli.cli_command().name(name));
|
||||||
if let Some(handler) = handlers.get(&Some(ctx_ty)) {
|
|
||||||
handler.cli()
|
|
||||||
} else if let Some(handler) = handlers.get(&None) {
|
|
||||||
handler.cli()
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
) {
|
|
||||||
cmd = cmd.subcommand(cli.cli_command(ctx_ty).name(name));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let matches = cmd.get_matches_from(args);
|
let matches = cmd.get_matches_from(args);
|
||||||
let config = Config::from_arg_matches(&matches)?;
|
let config = Config::from_arg_matches(&matches)?;
|
||||||
let ctx = (self.make_ctx)(config)?;
|
let ctx = (self.make_ctx)(config)?;
|
||||||
let root_handler = AnyHandler::new(self.root_handler);
|
let root_handler = AnyHandler::new(self.root_handler);
|
||||||
let (method, params) = root_handler.cli_parse(&matches, ctx_ty)?;
|
let (method, params) = root_handler.cli_parse(&matches)?;
|
||||||
let res = root_handler.handle_sync(HandleAnyArgs {
|
let res = root_handler.handle_sync(HandleAnyArgs {
|
||||||
context: ctx.clone().upcast(),
|
context: ctx.clone(),
|
||||||
parent_method: VecDeque::new(),
|
parent_method: VecDeque::new(),
|
||||||
method: method.clone(),
|
method: method.clone(),
|
||||||
params: params.clone(),
|
params: params.clone(),
|
||||||
@@ -72,7 +61,7 @@ impl<Context: crate::Context + Clone, Config: CommandFactory + FromArgMatches>
|
|||||||
})?;
|
})?;
|
||||||
root_handler.cli_display(
|
root_handler.cli_display(
|
||||||
HandleAnyArgs {
|
HandleAnyArgs {
|
||||||
context: ctx.upcast(),
|
context: ctx,
|
||||||
parent_method: VecDeque::new(),
|
parent_method: VecDeque::new(),
|
||||||
method,
|
method,
|
||||||
params,
|
params,
|
||||||
@@ -220,12 +209,12 @@ where
|
|||||||
type Err = RemoteHandler::Err;
|
type Err = RemoteHandler::Err;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Context, RemoteContext, RemoteHandler, Extra> Handler<Context>
|
impl<Context, RemoteContext, RemoteHandler, Extra> HandlerFor<Context>
|
||||||
for CallRemoteHandler<Context, RemoteContext, RemoteHandler, Extra>
|
for CallRemoteHandler<Context, RemoteContext, RemoteHandler, Extra>
|
||||||
where
|
where
|
||||||
Context: CallRemote<RemoteContext, Extra>,
|
Context: CallRemote<RemoteContext, Extra>,
|
||||||
RemoteContext: IntoContext,
|
RemoteContext: crate::Context,
|
||||||
RemoteHandler: Handler<RemoteContext>,
|
RemoteHandler: HandlerFor<RemoteContext>,
|
||||||
RemoteHandler::Params: Serialize,
|
RemoteHandler::Params: Serialize,
|
||||||
RemoteHandler::InheritedParams: Serialize,
|
RemoteHandler::InheritedParams: Serialize,
|
||||||
RemoteHandler::Ok: DeserializeOwned,
|
RemoteHandler::Ok: DeserializeOwned,
|
||||||
@@ -294,3 +283,48 @@ where
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl<Context, RemoteContext, RemoteHandler, Extra> CliBindings<Context>
|
||||||
|
for CallRemoteHandler<Context, RemoteContext, RemoteHandler, Extra>
|
||||||
|
where
|
||||||
|
Context: crate::Context,
|
||||||
|
RemoteHandler: CliBindings<Context>,
|
||||||
|
RemoteHandler::Params: Serialize,
|
||||||
|
RemoteHandler::InheritedParams: Serialize,
|
||||||
|
RemoteHandler::Ok: DeserializeOwned,
|
||||||
|
RemoteHandler::Err: From<RpcError>,
|
||||||
|
Extra: Send + Sync + 'static,
|
||||||
|
{
|
||||||
|
fn cli_command(&self) -> clap::Command {
|
||||||
|
self.handler.cli_command()
|
||||||
|
}
|
||||||
|
fn cli_parse(
|
||||||
|
&self,
|
||||||
|
matches: &clap::ArgMatches,
|
||||||
|
) -> Result<(VecDeque<&'static str>, Value), clap::Error> {
|
||||||
|
self.handler.cli_parse(matches)
|
||||||
|
}
|
||||||
|
fn cli_display(
|
||||||
|
&self,
|
||||||
|
HandlerArgs {
|
||||||
|
context,
|
||||||
|
parent_method,
|
||||||
|
method,
|
||||||
|
params,
|
||||||
|
inherited_params,
|
||||||
|
raw_params,
|
||||||
|
}: HandlerArgsFor<Context, Self>,
|
||||||
|
result: Self::Ok,
|
||||||
|
) -> Result<(), Self::Err> {
|
||||||
|
self.handler.cli_display(
|
||||||
|
HandlerArgs {
|
||||||
|
context,
|
||||||
|
parent_method,
|
||||||
|
method,
|
||||||
|
params: params.0,
|
||||||
|
inherited_params,
|
||||||
|
raw_params,
|
||||||
|
},
|
||||||
|
result,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
135
src/context.rs
135
src/context.rs
@@ -1,140 +1,7 @@
|
|||||||
use std::any::{Any, TypeId};
|
|
||||||
|
|
||||||
use imbl_value::imbl::OrdSet;
|
|
||||||
use tokio::runtime::Handle;
|
use tokio::runtime::Handle;
|
||||||
|
|
||||||
pub trait Context: Any + Send + Sync + 'static {
|
pub trait Context: Send + Sync + 'static {
|
||||||
fn inner_type_id(&self) -> TypeId {
|
|
||||||
<Self as Any>::type_id(&self)
|
|
||||||
}
|
|
||||||
fn runtime(&self) -> Handle {
|
fn runtime(&self) -> Handle {
|
||||||
Handle::current()
|
Handle::current()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(private_bounds)]
|
|
||||||
pub trait IntoContext: sealed::Sealed + Any + Send + Sync + Sized + 'static {
|
|
||||||
fn runtime(&self) -> Handle;
|
|
||||||
fn type_ids() -> Option<OrdSet<TypeId>>;
|
|
||||||
fn inner_type_id(&self) -> TypeId;
|
|
||||||
fn upcast(self) -> AnyContext;
|
|
||||||
fn downcast(value: AnyContext) -> Result<Self, AnyContext>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C: Context + Sized> IntoContext for C {
|
|
||||||
fn runtime(&self) -> Handle {
|
|
||||||
<C as Context>::runtime(&self)
|
|
||||||
}
|
|
||||||
fn type_ids() -> Option<OrdSet<TypeId>> {
|
|
||||||
let mut set = OrdSet::new();
|
|
||||||
set.insert(TypeId::of::<C>());
|
|
||||||
Some(set)
|
|
||||||
}
|
|
||||||
fn inner_type_id(&self) -> TypeId {
|
|
||||||
TypeId::of::<C>()
|
|
||||||
}
|
|
||||||
fn upcast(self) -> AnyContext {
|
|
||||||
AnyContext::new(self)
|
|
||||||
}
|
|
||||||
fn downcast(value: AnyContext) -> Result<Self, AnyContext> {
|
|
||||||
if value.0.inner_type_id() == TypeId::of::<C>() {
|
|
||||||
unsafe { Ok(value.downcast_unchecked::<C>()) }
|
|
||||||
} else {
|
|
||||||
Err(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum EitherContext<C1, C2> {
|
|
||||||
C1(C1),
|
|
||||||
C2(C2),
|
|
||||||
}
|
|
||||||
impl<C1: IntoContext, C2: IntoContext> IntoContext for EitherContext<C1, C2> {
|
|
||||||
fn runtime(&self) -> Handle {
|
|
||||||
match self {
|
|
||||||
Self::C1(a) => a.runtime(),
|
|
||||||
Self::C2(a) => a.runtime(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn type_ids() -> Option<OrdSet<TypeId>> {
|
|
||||||
let mut set = OrdSet::new();
|
|
||||||
set.extend(C1::type_ids()?);
|
|
||||||
set.extend(C2::type_ids()?);
|
|
||||||
Some(set)
|
|
||||||
}
|
|
||||||
fn inner_type_id(&self) -> TypeId {
|
|
||||||
match self {
|
|
||||||
EitherContext::C1(c) => c.inner_type_id(),
|
|
||||||
EitherContext::C2(c) => c.inner_type_id(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn downcast(value: AnyContext) -> Result<Self, AnyContext> {
|
|
||||||
match C1::downcast(value) {
|
|
||||||
Ok(a) => Ok(EitherContext::C1(a)),
|
|
||||||
Err(value) => match C2::downcast(value) {
|
|
||||||
Ok(a) => Ok(EitherContext::C2(a)),
|
|
||||||
Err(value) => Err(value),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn upcast(self) -> AnyContext {
|
|
||||||
match self {
|
|
||||||
Self::C1(c) => c.upcast(),
|
|
||||||
Self::C2(c) => c.upcast(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<C1, C2> From<C1> for EitherContext<C1, C2> {}
|
|
||||||
impl<C1, C2> From<C2> for EitherContext<C1, C2> {}
|
|
||||||
|
|
||||||
pub struct AnyContext(Box<dyn Context>);
|
|
||||||
impl AnyContext {
|
|
||||||
pub fn new<C: Context>(value: C) -> Self {
|
|
||||||
Self(Box::new(value))
|
|
||||||
}
|
|
||||||
unsafe fn downcast_unchecked<C: Context>(self) -> C {
|
|
||||||
let raw: *mut dyn Context = Box::into_raw(self.0);
|
|
||||||
*Box::from_raw(raw as *mut C)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IntoContext for AnyContext {
|
|
||||||
fn runtime(&self) -> Handle {
|
|
||||||
self.0.runtime()
|
|
||||||
}
|
|
||||||
fn type_ids() -> Option<OrdSet<TypeId>> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
fn inner_type_id(&self) -> TypeId {
|
|
||||||
self.0.inner_type_id()
|
|
||||||
}
|
|
||||||
fn downcast(value: AnyContext) -> Result<Self, AnyContext> {
|
|
||||||
Ok(value)
|
|
||||||
}
|
|
||||||
fn upcast(self) -> AnyContext {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) mod sealed {
|
|
||||||
use std::any::TypeId;
|
|
||||||
|
|
||||||
pub(crate) trait Sealed {
|
|
||||||
fn contains_type_id(id: TypeId) -> bool;
|
|
||||||
}
|
|
||||||
impl<C: super::Context> Sealed for C {
|
|
||||||
fn contains_type_id(id: TypeId) -> bool {
|
|
||||||
id == TypeId::of::<C>()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<C1: super::IntoContext, C2: super::IntoContext> Sealed for super::EitherContext<C1, C2> {
|
|
||||||
fn contains_type_id(id: TypeId) -> bool {
|
|
||||||
C1::contains_type_id(id) || C2::contains_type_id(id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl Sealed for super::AnyContext {
|
|
||||||
fn contains_type_id(_: TypeId) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -3,22 +3,22 @@ use std::collections::VecDeque;
|
|||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
use clap::{CommandFactory, FromArgMatches};
|
use clap::{CommandFactory, FromArgMatches};
|
||||||
use imbl_value::imbl::{OrdMap, OrdSet};
|
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 yajrc::RpcError;
|
||||||
|
|
||||||
use crate::util::{internal_error, Flat, PhantomData};
|
use crate::util::{Flat, PhantomData};
|
||||||
use crate::{
|
use crate::{
|
||||||
AnyContext, CallRemote, CliBindings, EitherContext, Empty, Handler, HandlerArgs,
|
CallRemote, CallRemoteHandler, CliBindings, DynHandler, Handler, HandlerArgs, HandlerArgsFor,
|
||||||
HandlerArgsFor, HandlerTypes, IntoContext, PrintCliResult,
|
HandlerFor, HandlerTypes, OrEmpty, PrintCliResult, WithContext,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait HandlerExt<Context: IntoContext>: Handler<Context> + Sized {
|
pub trait HandlerExt<Context: crate::Context>: HandlerFor<Context> + Sized {
|
||||||
fn no_cli(self) -> NoCli<Self>;
|
fn no_cli(self) -> NoCli<Self>;
|
||||||
fn no_display(self) -> NoDisplay<Self>;
|
fn no_display(self) -> NoDisplay<Self>;
|
||||||
fn with_custom_display<C: IntoContext, P>(self, display: P) -> CustomDisplay<P, Self>
|
fn with_custom_display<C: crate::Context, P>(self, display: P) -> CustomDisplay<P, Self>
|
||||||
where
|
where
|
||||||
P: PrintCliResult<
|
P: PrintCliResult<
|
||||||
C,
|
C,
|
||||||
@@ -27,7 +27,7 @@ pub trait HandlerExt<Context: IntoContext>: Handler<Context> + Sized {
|
|||||||
Ok = Self::Ok,
|
Ok = Self::Ok,
|
||||||
Err = Self::Err,
|
Err = Self::Err,
|
||||||
>;
|
>;
|
||||||
fn with_custom_display_fn<C: IntoContext, F>(
|
fn with_custom_display_fn<C: crate::Context, F>(
|
||||||
self,
|
self,
|
||||||
display: F,
|
display: F,
|
||||||
) -> CustomDisplayFn<F, Self, Context>
|
) -> CustomDisplayFn<F, Self, Context>
|
||||||
@@ -39,17 +39,17 @@ pub trait HandlerExt<Context: IntoContext>: Handler<Context> + Sized {
|
|||||||
) -> InheritanceHandler<Params, InheritedParams, Self, F>
|
) -> InheritanceHandler<Params, InheritedParams, Self, F>
|
||||||
where
|
where
|
||||||
F: Fn(Params, InheritedParams) -> Self::InheritedParams;
|
F: Fn(Params, InheritedParams) -> Self::InheritedParams;
|
||||||
fn with_call_remote<C>(self) -> RemoteCaller<C, Self>;
|
fn with_call_remote<C>(self) -> RemoteCaller<C, Context, Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Context: IntoContext, T: Handler<Context> + Sized> HandlerExt<Context> for T {
|
impl<Context: crate::Context, T: HandlerFor<Context> + Sized> HandlerExt<Context> for T {
|
||||||
fn no_cli(self) -> NoCli<Self> {
|
fn no_cli(self) -> NoCli<Self> {
|
||||||
NoCli(self)
|
NoCli(self)
|
||||||
}
|
}
|
||||||
fn no_display(self) -> NoDisplay<Self> {
|
fn no_display(self) -> NoDisplay<Self> {
|
||||||
NoDisplay(self)
|
NoDisplay(self)
|
||||||
}
|
}
|
||||||
fn with_custom_display<C: IntoContext, P>(self, display: P) -> CustomDisplay<P, Self>
|
fn with_custom_display<C: crate::Context, P>(self, display: P) -> CustomDisplay<P, Self>
|
||||||
where
|
where
|
||||||
P: PrintCliResult<
|
P: PrintCliResult<
|
||||||
C,
|
C,
|
||||||
@@ -64,7 +64,7 @@ impl<Context: IntoContext, T: Handler<Context> + Sized> HandlerExt<Context> for
|
|||||||
handler: self,
|
handler: self,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn with_custom_display_fn<C: IntoContext, F>(
|
fn with_custom_display_fn<C: crate::Context, F>(
|
||||||
self,
|
self,
|
||||||
display: F,
|
display: F,
|
||||||
) -> CustomDisplayFn<F, Self, Context>
|
) -> CustomDisplayFn<F, Self, Context>
|
||||||
@@ -90,7 +90,7 @@ impl<Context: IntoContext, T: Handler<Context> + Sized> HandlerExt<Context> for
|
|||||||
inherit: f,
|
inherit: f,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn with_call_remote<C>(self) -> RemoteCaller<C, Self> {
|
fn with_call_remote<C>(self) -> RemoteCaller<C, Context, Self> {
|
||||||
RemoteCaller {
|
RemoteCaller {
|
||||||
_phantom: PhantomData::new(),
|
_phantom: PhantomData::new(),
|
||||||
handler: self,
|
handler: self,
|
||||||
@@ -106,21 +106,10 @@ impl<H: HandlerTypes> HandlerTypes for NoCli<H> {
|
|||||||
type Ok = H::Ok;
|
type Ok = H::Ok;
|
||||||
type Err = H::Err;
|
type Err = H::Err;
|
||||||
}
|
}
|
||||||
// TODO: implement Handler
|
impl<Context, H> HandlerFor<Context> for NoCli<H>
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct NoDisplay<H>(pub H);
|
|
||||||
impl<H: HandlerTypes> HandlerTypes for NoDisplay<H> {
|
|
||||||
type Params = H::Params;
|
|
||||||
type InheritedParams = H::InheritedParams;
|
|
||||||
type Ok = H::Ok;
|
|
||||||
type Err = H::Err;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Context, H> Handler<Context> for NoDisplay<H>
|
|
||||||
where
|
where
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
H: Handler<Context>,
|
H: HandlerFor<Context>,
|
||||||
{
|
{
|
||||||
fn handle_sync(
|
fn handle_sync(
|
||||||
&self,
|
&self,
|
||||||
@@ -164,23 +153,99 @@ where
|
|||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
fn metadata(
|
fn metadata(&self, method: VecDeque<&'static str>) -> OrdMap<&'static str, Value> {
|
||||||
|
self.0.metadata(method)
|
||||||
|
}
|
||||||
|
fn method_from_dots(&self, method: &str) -> Option<VecDeque<&'static str>> {
|
||||||
|
self.0.method_from_dots(method)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<Context, H> CliBindings<Context> for NoCli<H>
|
||||||
|
where
|
||||||
|
Context: crate::Context,
|
||||||
|
H: HandlerTypes,
|
||||||
|
{
|
||||||
|
const NO_CLI: bool = true;
|
||||||
|
fn cli_command(&self) -> clap::Command {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
fn cli_parse(
|
||||||
&self,
|
&self,
|
||||||
method: VecDeque<&'static str>,
|
_: &clap::ArgMatches,
|
||||||
ctx_ty: TypeId,
|
) -> Result<(VecDeque<&'static str>, Value), clap::Error> {
|
||||||
) -> OrdMap<&'static str, Value> {
|
unimplemented!()
|
||||||
self.0.metadata(method, ctx_ty)
|
|
||||||
}
|
}
|
||||||
fn contexts(&self) -> Option<OrdSet<TypeId>> {
|
fn cli_display(&self, _: HandlerArgsFor<Context, Self>, _: Self::Ok) -> Result<(), Self::Err> {
|
||||||
self.0.contexts()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
fn method_from_dots(&self, method: &str, ctx_ty: TypeId) -> Option<VecDeque<&'static str>> {
|
}
|
||||||
self.0.method_from_dots(method, ctx_ty)
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct NoDisplay<H>(pub H);
|
||||||
|
impl<H: HandlerTypes> HandlerTypes for NoDisplay<H> {
|
||||||
|
type Params = H::Params;
|
||||||
|
type InheritedParams = H::InheritedParams;
|
||||||
|
type Ok = H::Ok;
|
||||||
|
type Err = H::Err;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Context, H> HandlerFor<Context> for NoDisplay<H>
|
||||||
|
where
|
||||||
|
Context: crate::Context,
|
||||||
|
H: HandlerFor<Context>,
|
||||||
|
{
|
||||||
|
fn handle_sync(
|
||||||
|
&self,
|
||||||
|
HandlerArgs {
|
||||||
|
context,
|
||||||
|
parent_method,
|
||||||
|
method,
|
||||||
|
params,
|
||||||
|
inherited_params,
|
||||||
|
raw_params,
|
||||||
|
}: HandlerArgsFor<Context, Self>,
|
||||||
|
) -> Result<Self::Ok, Self::Err> {
|
||||||
|
self.0.handle_sync(HandlerArgs {
|
||||||
|
context,
|
||||||
|
parent_method,
|
||||||
|
method,
|
||||||
|
params,
|
||||||
|
inherited_params,
|
||||||
|
raw_params,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
async fn handle_async(
|
||||||
|
&self,
|
||||||
|
HandlerArgs {
|
||||||
|
context,
|
||||||
|
parent_method,
|
||||||
|
method,
|
||||||
|
params,
|
||||||
|
inherited_params,
|
||||||
|
raw_params,
|
||||||
|
}: HandlerArgsFor<Context, Self>,
|
||||||
|
) -> Result<Self::Ok, Self::Err> {
|
||||||
|
self.0
|
||||||
|
.handle_async(HandlerArgs {
|
||||||
|
context,
|
||||||
|
parent_method,
|
||||||
|
method,
|
||||||
|
params,
|
||||||
|
inherited_params,
|
||||||
|
raw_params,
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
fn metadata(&self, method: VecDeque<&'static str>) -> OrdMap<&'static str, Value> {
|
||||||
|
self.0.metadata(method)
|
||||||
|
}
|
||||||
|
fn method_from_dots(&self, method: &str) -> Option<VecDeque<&'static str>> {
|
||||||
|
self.0.method_from_dots(method)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<Context, H> PrintCliResult<Context> for NoDisplay<H>
|
impl<Context, H> PrintCliResult<Context> for NoDisplay<H>
|
||||||
where
|
where
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
H: HandlerTypes,
|
H: HandlerTypes,
|
||||||
H::Params: FromArgMatches + CommandFactory + Serialize,
|
H::Params: FromArgMatches + CommandFactory + Serialize,
|
||||||
{
|
{
|
||||||
@@ -204,10 +269,10 @@ where
|
|||||||
type Err = H::Err;
|
type Err = H::Err;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Context, P, H> Handler<Context> for CustomDisplay<P, H>
|
impl<Context, P, H> HandlerFor<Context> for CustomDisplay<P, H>
|
||||||
where
|
where
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
H: Handler<Context>,
|
H: HandlerFor<Context>,
|
||||||
P: Send + Sync + Clone + 'static,
|
P: Send + Sync + Clone + 'static,
|
||||||
{
|
{
|
||||||
fn handle_sync(
|
fn handle_sync(
|
||||||
@@ -252,23 +317,16 @@ where
|
|||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
fn metadata(
|
fn metadata(&self, method: VecDeque<&'static str>) -> OrdMap<&'static str, Value> {
|
||||||
&self,
|
self.handler.metadata(method)
|
||||||
method: VecDeque<&'static str>,
|
|
||||||
ctx_ty: TypeId,
|
|
||||||
) -> OrdMap<&'static str, Value> {
|
|
||||||
self.handler.metadata(method, ctx_ty)
|
|
||||||
}
|
}
|
||||||
fn contexts(&self) -> Option<OrdSet<TypeId>> {
|
fn method_from_dots(&self, method: &str) -> Option<VecDeque<&'static str>> {
|
||||||
self.handler.contexts()
|
self.handler.method_from_dots(method)
|
||||||
}
|
|
||||||
fn method_from_dots(&self, method: &str, ctx_ty: TypeId) -> Option<VecDeque<&'static str>> {
|
|
||||||
self.handler.method_from_dots(method, ctx_ty)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<Context, P, H> PrintCliResult<Context> for CustomDisplay<P, H>
|
impl<Context, P, H> PrintCliResult<Context> for CustomDisplay<P, H>
|
||||||
where
|
where
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
H: HandlerTypes,
|
H: HandlerTypes,
|
||||||
P: PrintCliResult<
|
P: PrintCliResult<
|
||||||
Context,
|
Context,
|
||||||
@@ -307,7 +365,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CustomDisplayFn<F, H, Context = AnyContext> {
|
pub struct CustomDisplayFn<F, H, Context> {
|
||||||
_phantom: PhantomData<Context>,
|
_phantom: PhantomData<Context>,
|
||||||
print: F,
|
print: F,
|
||||||
handler: H,
|
handler: H,
|
||||||
@@ -339,11 +397,11 @@ where
|
|||||||
type Err = H::Err;
|
type Err = H::Err;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Context, F, H, C> Handler<Context> for CustomDisplayFn<F, H, C>
|
impl<Context, F, H, C> HandlerFor<Context> for CustomDisplayFn<F, H, C>
|
||||||
where
|
where
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
C: 'static,
|
C: 'static,
|
||||||
H: Handler<Context>,
|
H: HandlerFor<Context>,
|
||||||
F: Send + Sync + Clone + 'static,
|
F: Send + Sync + Clone + 'static,
|
||||||
{
|
{
|
||||||
fn handle_sync(
|
fn handle_sync(
|
||||||
@@ -388,23 +446,16 @@ where
|
|||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
fn metadata(
|
fn metadata(&self, method: VecDeque<&'static str>) -> OrdMap<&'static str, Value> {
|
||||||
&self,
|
self.handler.metadata(method)
|
||||||
method: VecDeque<&'static str>,
|
|
||||||
ctx_ty: TypeId,
|
|
||||||
) -> OrdMap<&'static str, Value> {
|
|
||||||
self.handler.metadata(method, ctx_ty)
|
|
||||||
}
|
}
|
||||||
fn contexts(&self) -> Option<OrdSet<TypeId>> {
|
fn method_from_dots(&self, method: &str) -> Option<VecDeque<&'static str>> {
|
||||||
self.handler.contexts()
|
self.handler.method_from_dots(method)
|
||||||
}
|
|
||||||
fn method_from_dots(&self, method: &str, ctx_ty: TypeId) -> Option<VecDeque<&'static str>> {
|
|
||||||
self.handler.method_from_dots(method, ctx_ty)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<F, H, Context> PrintCliResult<Context> for CustomDisplayFn<F, H, Context>
|
impl<F, H, Context> PrintCliResult<Context> for CustomDisplayFn<F, H, Context>
|
||||||
where
|
where
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
H: HandlerTypes,
|
H: HandlerTypes,
|
||||||
F: Fn(HandlerArgsFor<Context, H>, H::Ok) -> Result<(), H::Err> + Send + Sync + Clone + 'static,
|
F: Fn(HandlerArgsFor<Context, H>, H::Ok) -> Result<(), H::Err> + Send + Sync + Clone + 'static,
|
||||||
{
|
{
|
||||||
@@ -434,11 +485,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RemoteCaller<Context, H> {
|
pub struct RemoteCaller<Context, RemoteContext, H> {
|
||||||
_phantom: PhantomData<Context>,
|
_phantom: PhantomData<(Context, RemoteContext)>,
|
||||||
handler: H,
|
handler: H,
|
||||||
}
|
}
|
||||||
impl<Context, H: Clone> Clone for RemoteCaller<Context, H> {
|
impl<Context, RemoteContext, H: Clone> Clone for RemoteCaller<Context, RemoteContext, H> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
_phantom: PhantomData::new(),
|
_phantom: PhantomData::new(),
|
||||||
@@ -446,113 +497,170 @@ impl<Context, H: Clone> Clone for RemoteCaller<Context, H> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<Context, H: Debug> Debug for RemoteCaller<Context, H> {
|
impl<Context, RemoteContext, H: Debug> Debug for RemoteCaller<Context, RemoteContext, 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("RemoteCaller").field(&self.handler).finish()
|
f.debug_tuple("RemoteCaller").field(&self.handler).finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<Context, H> HandlerTypes for RemoteCaller<Context, H>
|
|
||||||
where
|
|
||||||
H: HandlerTypes,
|
|
||||||
{
|
|
||||||
type Params = H::Params;
|
|
||||||
type InheritedParams = H::InheritedParams;
|
|
||||||
type Ok = H::Ok;
|
|
||||||
type Err = H::Err;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Context, RemoteContext, H> Handler<EitherContext<Context, RemoteContext>>
|
// impl<Context, RemoteContext, H> HandlerTypes for RemoteCaller<Context, RemoteContext, H>
|
||||||
for RemoteCaller<Context, H>
|
// where
|
||||||
|
// H: HandlerTypes,
|
||||||
|
// {
|
||||||
|
// type Params = H::Params;
|
||||||
|
// type InheritedParams = H::InheritedParams;
|
||||||
|
// type Ok = H::Ok;
|
||||||
|
// type Err = H::Err;
|
||||||
|
// }
|
||||||
|
// impl<Context, RemoteContext, H> HandlerFor<RemoteContext>
|
||||||
|
// for RemoteCaller<Context, RemoteContext, H>
|
||||||
|
// where
|
||||||
|
// Context: CallRemote<RemoteContext>,
|
||||||
|
// RemoteContext: crate::Context,
|
||||||
|
// H: HandlerFor<RemoteContext>,
|
||||||
|
// H::Params: Serialize,
|
||||||
|
// H::InheritedParams: Serialize,
|
||||||
|
// H::Ok: DeserializeOwned,
|
||||||
|
// H::Err: From<RpcError>,
|
||||||
|
// {
|
||||||
|
// async fn handle_async(
|
||||||
|
// &self,
|
||||||
|
// HandlerArgs {
|
||||||
|
// context,
|
||||||
|
// parent_method,
|
||||||
|
// method,
|
||||||
|
// params,
|
||||||
|
// inherited_params,
|
||||||
|
// raw_params,
|
||||||
|
// }: HandlerArgsFor<RemoteContext, Self>,
|
||||||
|
// ) -> Result<Self::Ok, Self::Err> {
|
||||||
|
// self.handler
|
||||||
|
// .handle_async(HandlerArgs {
|
||||||
|
// context,
|
||||||
|
// parent_method,
|
||||||
|
// method,
|
||||||
|
// params,
|
||||||
|
// inherited_params,
|
||||||
|
// raw_params,
|
||||||
|
// })
|
||||||
|
// .await
|
||||||
|
// }
|
||||||
|
// 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>> {
|
||||||
|
// Context::type_ids()
|
||||||
|
// }
|
||||||
|
// fn method_from_dots(&self, method: &str, ctx_ty: TypeId) -> Option<VecDeque<&'static str>> {
|
||||||
|
// self.handler.method_from_dots(method, ctx_ty)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// impl<Context, RemoteContext, H> HandlerFor<Context> for RemoteCaller<Context, RemoteContext, H>
|
||||||
|
// where
|
||||||
|
// Context: CallRemote<RemoteContext>,
|
||||||
|
// RemoteContext: crate::Context,
|
||||||
|
// H: HandlerFor<RemoteContext>,
|
||||||
|
// H::Params: Serialize,
|
||||||
|
// H::InheritedParams: Serialize,
|
||||||
|
// H::Ok: DeserializeOwned,
|
||||||
|
// H::Err: From<RpcError>,
|
||||||
|
// {
|
||||||
|
// async fn handle_async(
|
||||||
|
// &self,
|
||||||
|
// HandlerArgs {
|
||||||
|
// context,
|
||||||
|
// parent_method,
|
||||||
|
// method,
|
||||||
|
// params,
|
||||||
|
// inherited_params,
|
||||||
|
// raw_params,
|
||||||
|
// }: HandlerArgsFor<Context, Self>,
|
||||||
|
// ) -> Result<Self::Ok, Self::Err> {
|
||||||
|
// let full_method = parent_method.into_iter().chain(method).collect::<Vec<_>>();
|
||||||
|
// match context
|
||||||
|
// .call_remote(&full_method.join("."), raw_params, Empty {})
|
||||||
|
// .await
|
||||||
|
// {
|
||||||
|
// Ok(a) => imbl_value::from_value(a)
|
||||||
|
// .map_err(internal_error)
|
||||||
|
// .map_err(Self::Err::from),
|
||||||
|
// Err(e) => Err(Self::Err::from(e)),
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// 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>> {
|
||||||
|
// Context::type_ids()
|
||||||
|
// }
|
||||||
|
// fn method_from_dots(&self, method: &str, ctx_ty: TypeId) -> Option<VecDeque<&'static str>> {
|
||||||
|
// self.handler.method_from_dots(method, ctx_ty)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// impl<Context, RemoteContext, H> PrintCliResult<Context> for RemoteCaller<Context, RemoteContext, H>
|
||||||
|
// where
|
||||||
|
// Context: crate::Context,
|
||||||
|
// H: PrintCliResult<Context>,
|
||||||
|
// {
|
||||||
|
// fn print(
|
||||||
|
// &self,
|
||||||
|
// HandlerArgs {
|
||||||
|
// context,
|
||||||
|
// parent_method,
|
||||||
|
// method,
|
||||||
|
// params,
|
||||||
|
// inherited_params,
|
||||||
|
// raw_params,
|
||||||
|
// }: HandlerArgsFor<Context, Self>,
|
||||||
|
// result: Self::Ok,
|
||||||
|
// ) -> Result<(), Self::Err> {
|
||||||
|
// self.handler.print(
|
||||||
|
// HandlerArgs {
|
||||||
|
// context,
|
||||||
|
// parent_method,
|
||||||
|
// method,
|
||||||
|
// params,
|
||||||
|
// inherited_params,
|
||||||
|
// raw_params,
|
||||||
|
// },
|
||||||
|
// result,
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
impl<Context, H, Inherited, LocalContext, RemoteContext> Handler<Inherited>
|
||||||
|
for WithContext<Context, RemoteCaller<LocalContext, RemoteContext, H>>
|
||||||
where
|
where
|
||||||
Context: CallRemote<RemoteContext>,
|
Context: crate::Context,
|
||||||
RemoteContext: IntoContext,
|
LocalContext: crate::Context + CallRemote<RemoteContext>,
|
||||||
H: Handler<RemoteContext>,
|
RemoteContext: crate::Context,
|
||||||
H::Params: Serialize,
|
H: HandlerFor<RemoteContext> + CliBindings<LocalContext>,
|
||||||
H::InheritedParams: Serialize,
|
H::Ok: Serialize + DeserializeOwned,
|
||||||
H::Ok: DeserializeOwned,
|
|
||||||
H::Err: From<RpcError>,
|
H::Err: From<RpcError>,
|
||||||
|
H::Params: Serialize + DeserializeOwned,
|
||||||
|
H::InheritedParams: Serialize + OrEmpty<Inherited>,
|
||||||
|
RpcError: From<H::Err>,
|
||||||
|
Inherited: Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
async fn handle_async(
|
type H = H;
|
||||||
&self,
|
fn handler_for<C: crate::Context>(self) -> Option<DynHandler<C, Inherited>> {
|
||||||
HandlerArgs {
|
if TypeId::of::<C>() == TypeId::of::<RemoteContext>() {
|
||||||
context,
|
DynHandler::new(self.handler.handler.no_cli())
|
||||||
parent_method,
|
} else if TypeId::of::<C>() == TypeId::of::<LocalContext>() {
|
||||||
method,
|
DynHandler::new(CallRemoteHandler::<LocalContext, RemoteContext, _>::new(
|
||||||
params,
|
self.handler.handler,
|
||||||
inherited_params,
|
))
|
||||||
raw_params,
|
} else {
|
||||||
}: HandlerArgsFor<EitherContext<Context, RemoteContext>, Self>,
|
None
|
||||||
) -> Result<Self::Ok, Self::Err> {
|
|
||||||
match context {
|
|
||||||
EitherContext::C1(context) => {
|
|
||||||
let full_method = parent_method.into_iter().chain(method).collect::<Vec<_>>();
|
|
||||||
match context
|
|
||||||
.call_remote(&full_method.join("."), raw_params, Empty {})
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(a) => imbl_value::from_value(a)
|
|
||||||
.map_err(internal_error)
|
|
||||||
.map_err(Self::Err::from),
|
|
||||||
Err(e) => Err(Self::Err::from(e)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EitherContext::C2(context) => {
|
|
||||||
self.handler
|
|
||||||
.handle_async(HandlerArgs {
|
|
||||||
context,
|
|
||||||
parent_method,
|
|
||||||
method,
|
|
||||||
params,
|
|
||||||
inherited_params,
|
|
||||||
raw_params,
|
|
||||||
})
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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>> {
|
|
||||||
Context::type_ids()
|
|
||||||
}
|
|
||||||
fn method_from_dots(&self, method: &str, ctx_ty: TypeId) -> Option<VecDeque<&'static str>> {
|
|
||||||
self.handler.method_from_dots(method, ctx_ty)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<Context, H> PrintCliResult<Context> for RemoteCaller<Context, H>
|
|
||||||
where
|
|
||||||
Context: IntoContext,
|
|
||||||
H: PrintCliResult<Context>,
|
|
||||||
{
|
|
||||||
fn print(
|
|
||||||
&self,
|
|
||||||
HandlerArgs {
|
|
||||||
context,
|
|
||||||
parent_method,
|
|
||||||
method,
|
|
||||||
params,
|
|
||||||
inherited_params,
|
|
||||||
raw_params,
|
|
||||||
}: HandlerArgsFor<Context, Self>,
|
|
||||||
result: Self::Ok,
|
|
||||||
) -> Result<(), Self::Err> {
|
|
||||||
self.handler.print(
|
|
||||||
HandlerArgs {
|
|
||||||
context,
|
|
||||||
parent_method,
|
|
||||||
method,
|
|
||||||
params,
|
|
||||||
inherited_params,
|
|
||||||
raw_params,
|
|
||||||
},
|
|
||||||
result,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct InheritanceHandler<Params, InheritedParams, H, F> {
|
pub struct InheritanceHandler<Params, InheritedParams, H, F> {
|
||||||
@@ -593,13 +701,13 @@ where
|
|||||||
type Err = H::Err;
|
type Err = H::Err;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Context, Params, InheritedParams, H, F> Handler<Context>
|
impl<Context, Params, InheritedParams, H, F> HandlerFor<Context>
|
||||||
for InheritanceHandler<Params, InheritedParams, H, F>
|
for InheritanceHandler<Params, InheritedParams, H, F>
|
||||||
where
|
where
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
Params: Send + Sync + 'static,
|
Params: Send + Sync + 'static,
|
||||||
InheritedParams: Send + Sync + 'static,
|
InheritedParams: Send + Sync + 'static,
|
||||||
H: Handler<Context>,
|
H: HandlerFor<Context>,
|
||||||
F: Fn(Params, InheritedParams) -> H::InheritedParams + Send + Sync + Clone + 'static,
|
F: Fn(Params, InheritedParams) -> H::InheritedParams + Send + Sync + Clone + 'static,
|
||||||
{
|
{
|
||||||
fn handle_sync(
|
fn handle_sync(
|
||||||
@@ -644,39 +752,31 @@ where
|
|||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
fn metadata(
|
fn metadata(&self, method: VecDeque<&'static str>) -> OrdMap<&'static str, Value> {
|
||||||
&self,
|
self.handler.metadata(method)
|
||||||
method: VecDeque<&'static str>,
|
|
||||||
ctx_ty: TypeId,
|
|
||||||
) -> OrdMap<&'static str, Value> {
|
|
||||||
self.handler.metadata(method, ctx_ty)
|
|
||||||
}
|
}
|
||||||
fn contexts(&self) -> Option<OrdSet<TypeId>> {
|
fn method_from_dots(&self, method: &str) -> Option<VecDeque<&'static str>> {
|
||||||
self.handler.contexts()
|
self.handler.method_from_dots(method)
|
||||||
}
|
|
||||||
fn method_from_dots(&self, method: &str, ctx_ty: TypeId) -> Option<VecDeque<&'static str>> {
|
|
||||||
self.handler.method_from_dots(method, ctx_ty)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Context, Params, InheritedParams, H, F> CliBindings<Context>
|
impl<Context, Params, InheritedParams, H, F> CliBindings<Context>
|
||||||
for InheritanceHandler<Params, InheritedParams, H, F>
|
for InheritanceHandler<Params, InheritedParams, H, F>
|
||||||
where
|
where
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
Params: Send + Sync + 'static,
|
Params: Send + Sync + 'static,
|
||||||
InheritedParams: Send + Sync + 'static,
|
InheritedParams: Send + Sync + 'static,
|
||||||
H: CliBindings<Context>,
|
H: CliBindings<Context>,
|
||||||
F: Fn(Params, InheritedParams) -> H::InheritedParams + Send + Sync + Clone + 'static,
|
F: Fn(Params, InheritedParams) -> H::InheritedParams + Send + Sync + Clone + 'static,
|
||||||
{
|
{
|
||||||
fn cli_command(&self, ctx_ty: TypeId) -> clap::Command {
|
fn cli_command(&self) -> clap::Command {
|
||||||
self.handler.cli_command(ctx_ty)
|
self.handler.cli_command()
|
||||||
}
|
}
|
||||||
fn cli_parse(
|
fn cli_parse(
|
||||||
&self,
|
&self,
|
||||||
matches: &clap::ArgMatches,
|
matches: &clap::ArgMatches,
|
||||||
ctx_ty: TypeId,
|
|
||||||
) -> Result<(VecDeque<&'static str>, Value), clap::Error> {
|
) -> Result<(VecDeque<&'static str>, Value), clap::Error> {
|
||||||
self.handler.cli_parse(matches, ctx_ty)
|
self.handler.cli_parse(matches)
|
||||||
}
|
}
|
||||||
fn cli_display(
|
fn cli_display(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
use std::any::TypeId;
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
@@ -11,8 +10,7 @@ use serde::Serialize;
|
|||||||
|
|
||||||
use crate::util::PhantomData;
|
use crate::util::PhantomData;
|
||||||
use crate::{
|
use crate::{
|
||||||
CliBindings, Empty, Handler, HandlerArgs, HandlerArgsFor, HandlerTypes, IntoContext,
|
CliBindings, Empty, HandlerArgs, HandlerArgsFor, HandlerFor, HandlerTypes, PrintCliResult,
|
||||||
PrintCliResult,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct FromFn<F, T, E, Args> {
|
pub struct FromFn<F, T, E, Args> {
|
||||||
@@ -46,7 +44,7 @@ impl<F, T, E, Args> std::fmt::Debug for FromFn<F, T, E, Args> {
|
|||||||
}
|
}
|
||||||
impl<Context, F, T, E, Args> PrintCliResult<Context> for FromFn<F, T, E, Args>
|
impl<Context, F, T, E, Args> PrintCliResult<Context> for FromFn<F, T, E, Args>
|
||||||
where
|
where
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
Self: HandlerTypes,
|
Self: HandlerTypes,
|
||||||
<Self as HandlerTypes>::Ok: Display,
|
<Self as HandlerTypes>::Ok: Display,
|
||||||
{
|
{
|
||||||
@@ -56,18 +54,17 @@ where
|
|||||||
}
|
}
|
||||||
impl<Context, F, T, E, Args> CliBindings<Context> for FromFn<F, T, E, Args>
|
impl<Context, F, T, E, Args> CliBindings<Context> for FromFn<F, T, E, Args>
|
||||||
where
|
where
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
Self: HandlerTypes,
|
Self: HandlerTypes,
|
||||||
Self::Params: CommandFactory + FromArgMatches + Serialize,
|
Self::Params: CommandFactory + FromArgMatches + Serialize,
|
||||||
Self: PrintCliResult<Context>,
|
Self: PrintCliResult<Context>,
|
||||||
{
|
{
|
||||||
fn cli_command(&self, _: TypeId) -> clap::Command {
|
fn cli_command(&self) -> clap::Command {
|
||||||
Self::Params::command()
|
Self::Params::command()
|
||||||
}
|
}
|
||||||
fn cli_parse(
|
fn cli_parse(
|
||||||
&self,
|
&self,
|
||||||
matches: &clap::ArgMatches,
|
matches: &clap::ArgMatches,
|
||||||
_: 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((
|
||||||
@@ -154,7 +151,7 @@ impl<F, Fut, T, E, Args> std::fmt::Debug for FromFnAsync<F, Fut, T, E, Args> {
|
|||||||
}
|
}
|
||||||
impl<Context, F, Fut, T, E, Args> PrintCliResult<Context> for FromFnAsync<F, Fut, T, E, Args>
|
impl<Context, F, Fut, T, E, Args> PrintCliResult<Context> for FromFnAsync<F, Fut, T, E, Args>
|
||||||
where
|
where
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
Self: HandlerTypes,
|
Self: HandlerTypes,
|
||||||
<Self as HandlerTypes>::Ok: Display,
|
<Self as HandlerTypes>::Ok: Display,
|
||||||
{
|
{
|
||||||
@@ -164,18 +161,17 @@ where
|
|||||||
}
|
}
|
||||||
impl<Context, F, Fut, T, E, Args> CliBindings<Context> for FromFnAsync<F, Fut, T, E, Args>
|
impl<Context, F, Fut, T, E, Args> CliBindings<Context> for FromFnAsync<F, Fut, T, E, Args>
|
||||||
where
|
where
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
Self: HandlerTypes,
|
Self: HandlerTypes,
|
||||||
Self::Params: CommandFactory + FromArgMatches + Serialize,
|
Self::Params: CommandFactory + FromArgMatches + Serialize,
|
||||||
Self: PrintCliResult<Context>,
|
Self: PrintCliResult<Context>,
|
||||||
{
|
{
|
||||||
fn cli_command(&self, _: TypeId) -> clap::Command {
|
fn cli_command(&self) -> clap::Command {
|
||||||
Self::Params::command()
|
Self::Params::command()
|
||||||
}
|
}
|
||||||
fn cli_parse(
|
fn cli_parse(
|
||||||
&self,
|
&self,
|
||||||
matches: &clap::ArgMatches,
|
matches: &clap::ArgMatches,
|
||||||
_: 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((
|
||||||
@@ -232,7 +228,7 @@ where
|
|||||||
+ 'static,
|
+ 'static,
|
||||||
T: Send + Sync + 'static,
|
T: Send + Sync + 'static,
|
||||||
E: Send + Sync + 'static,
|
E: Send + Sync + 'static,
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
Params: Send + Sync,
|
Params: Send + Sync,
|
||||||
InheritedParams: Send + Sync,
|
InheritedParams: Send + Sync,
|
||||||
{
|
{
|
||||||
@@ -242,7 +238,7 @@ where
|
|||||||
type Err = E;
|
type Err = E;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, T, E, Context, Params, InheritedParams> Handler<Context>
|
impl<F, T, E, Context, Params, InheritedParams> HandlerFor<Context>
|
||||||
for FromFn<F, T, E, HandlerArgs<Context, Params, InheritedParams>>
|
for FromFn<F, T, E, HandlerArgs<Context, Params, InheritedParams>>
|
||||||
where
|
where
|
||||||
F: Fn(HandlerArgs<Context, Params, InheritedParams>) -> Result<T, E>
|
F: Fn(HandlerArgs<Context, Params, InheritedParams>) -> Result<T, E>
|
||||||
@@ -252,7 +248,7 @@ where
|
|||||||
+ 'static,
|
+ 'static,
|
||||||
T: Send + Sync + 'static,
|
T: Send + Sync + 'static,
|
||||||
E: Send + Sync + 'static,
|
E: Send + Sync + 'static,
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
Params: Send + Sync + 'static,
|
Params: Send + Sync + 'static,
|
||||||
InheritedParams: Send + Sync + 'static,
|
InheritedParams: Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
@@ -272,7 +268,7 @@ where
|
|||||||
self.handle_async_with_sync(handle_args).await
|
self.handle_async_with_sync(handle_args).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn metadata(&self, _: VecDeque<&'static str>, _: TypeId) -> OrdMap<&'static str, Value> {
|
fn metadata(&self, _: VecDeque<&'static str>) -> OrdMap<&'static str, Value> {
|
||||||
self.metadata.clone()
|
self.metadata.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -283,7 +279,7 @@ where
|
|||||||
Fut: Future<Output = Result<T, E>> + Send + 'static,
|
Fut: Future<Output = Result<T, E>> + Send + 'static,
|
||||||
T: Send + Sync + 'static,
|
T: Send + Sync + 'static,
|
||||||
E: Send + Sync + 'static,
|
E: Send + Sync + 'static,
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
Params: Send + Sync,
|
Params: Send + Sync,
|
||||||
InheritedParams: Send + Sync,
|
InheritedParams: Send + Sync,
|
||||||
{
|
{
|
||||||
@@ -293,14 +289,14 @@ where
|
|||||||
type Err = E;
|
type Err = E;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, Fut, T, E, Context, Params, InheritedParams> Handler<Context>
|
impl<F, Fut, T, E, Context, Params, InheritedParams> HandlerFor<Context>
|
||||||
for FromFnAsync<F, Fut, T, E, HandlerArgs<Context, Params, InheritedParams>>
|
for FromFnAsync<F, Fut, T, E, HandlerArgs<Context, Params, InheritedParams>>
|
||||||
where
|
where
|
||||||
F: Fn(HandlerArgs<Context, Params, InheritedParams>) -> Fut + Send + Sync + Clone + 'static,
|
F: Fn(HandlerArgs<Context, Params, InheritedParams>) -> Fut + Send + Sync + Clone + 'static,
|
||||||
Fut: Future<Output = Result<T, E>> + Send + 'static,
|
Fut: Future<Output = Result<T, E>> + Send + 'static,
|
||||||
T: Send + Sync + 'static,
|
T: Send + Sync + 'static,
|
||||||
E: Send + Sync + 'static,
|
E: Send + Sync + 'static,
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
Params: Send + Sync + 'static,
|
Params: Send + Sync + 'static,
|
||||||
InheritedParams: Send + Sync + 'static,
|
InheritedParams: Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
@@ -310,7 +306,7 @@ where
|
|||||||
) -> Result<Self::Ok, Self::Err> {
|
) -> Result<Self::Ok, Self::Err> {
|
||||||
(self.function)(handle_args).await
|
(self.function)(handle_args).await
|
||||||
}
|
}
|
||||||
fn metadata(&self, _: VecDeque<&'static str>, _: TypeId) -> OrdMap<&'static str, Value> {
|
fn metadata(&self, _: VecDeque<&'static str>) -> OrdMap<&'static str, Value> {
|
||||||
self.metadata.clone()
|
self.metadata.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -327,9 +323,9 @@ where
|
|||||||
type Err = E;
|
type Err = E;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Context, F, T, E> Handler<Context> for FromFn<F, T, E, ()>
|
impl<Context, F, T, E> HandlerFor<Context> for FromFn<F, T, E, ()>
|
||||||
where
|
where
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
F: Fn() -> Result<T, E> + Send + Sync + Clone + 'static,
|
F: Fn() -> Result<T, E> + Send + Sync + Clone + 'static,
|
||||||
T: Send + Sync + 'static,
|
T: Send + Sync + 'static,
|
||||||
E: Send + Sync + 'static,
|
E: Send + Sync + 'static,
|
||||||
@@ -347,7 +343,7 @@ where
|
|||||||
self.handle_async_with_sync(handle_args).await
|
self.handle_async_with_sync(handle_args).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn metadata(&self, _: VecDeque<&'static str>, _: TypeId) -> OrdMap<&'static str, Value> {
|
fn metadata(&self, _: VecDeque<&'static str>) -> OrdMap<&'static str, Value> {
|
||||||
self.metadata.clone()
|
self.metadata.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -364,9 +360,9 @@ where
|
|||||||
type Err = E;
|
type Err = E;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Context, F, Fut, T, E> Handler<Context> for FromFnAsync<F, Fut, T, E, ()>
|
impl<Context, F, Fut, T, E> HandlerFor<Context> for FromFnAsync<F, Fut, T, E, ()>
|
||||||
where
|
where
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
F: Fn() -> Fut + Send + Sync + Clone + 'static,
|
F: Fn() -> Fut + Send + Sync + Clone + 'static,
|
||||||
Fut: Future<Output = Result<T, E>> + Send + 'static,
|
Fut: Future<Output = Result<T, E>> + Send + 'static,
|
||||||
T: Send + Sync + 'static,
|
T: Send + Sync + 'static,
|
||||||
@@ -375,14 +371,14 @@ where
|
|||||||
async fn handle_async(&self, _: HandlerArgsFor<Context, Self>) -> Result<Self::Ok, Self::Err> {
|
async fn handle_async(&self, _: HandlerArgsFor<Context, Self>) -> Result<Self::Ok, Self::Err> {
|
||||||
(self.function)().await
|
(self.function)().await
|
||||||
}
|
}
|
||||||
fn metadata(&self, _: VecDeque<&'static str>, _: TypeId) -> OrdMap<&'static str, Value> {
|
fn metadata(&self, _: VecDeque<&'static str>) -> OrdMap<&'static str, Value> {
|
||||||
self.metadata.clone()
|
self.metadata.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Context, F, T, E> HandlerTypes for FromFn<F, T, E, (Context,)>
|
impl<Context, F, T, E> HandlerTypes for FromFn<F, T, E, (Context,)>
|
||||||
where
|
where
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
F: Fn(Context) -> Result<T, E> + Send + Sync + Clone + 'static,
|
F: Fn(Context) -> Result<T, E> + Send + Sync + Clone + 'static,
|
||||||
T: Send + Sync + 'static,
|
T: Send + Sync + 'static,
|
||||||
E: Send + Sync + 'static,
|
E: Send + Sync + 'static,
|
||||||
@@ -393,9 +389,9 @@ where
|
|||||||
type Err = E;
|
type Err = E;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Context, F, T, E> Handler<Context> for FromFn<F, T, E, (Context,)>
|
impl<Context, F, T, E> HandlerFor<Context> for FromFn<F, T, E, (Context,)>
|
||||||
where
|
where
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
F: Fn(Context) -> Result<T, E> + Send + Sync + Clone + 'static,
|
F: Fn(Context) -> Result<T, E> + Send + Sync + Clone + 'static,
|
||||||
T: Send + Sync + 'static,
|
T: Send + Sync + 'static,
|
||||||
E: Send + Sync + 'static,
|
E: Send + Sync + 'static,
|
||||||
@@ -416,13 +412,13 @@ where
|
|||||||
self.handle_async_with_sync(handle_args).await
|
self.handle_async_with_sync(handle_args).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn metadata(&self, _: VecDeque<&'static str>, _: TypeId) -> OrdMap<&'static str, Value> {
|
fn metadata(&self, _: VecDeque<&'static str>) -> OrdMap<&'static str, Value> {
|
||||||
self.metadata.clone()
|
self.metadata.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<Context, F, Fut, T, E> HandlerTypes for FromFnAsync<F, Fut, T, E, (Context,)>
|
impl<Context, F, Fut, T, E> HandlerTypes for FromFnAsync<F, Fut, T, E, (Context,)>
|
||||||
where
|
where
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
F: Fn(Context) -> Fut + Send + Sync + Clone + 'static,
|
F: Fn(Context) -> Fut + Send + Sync + Clone + 'static,
|
||||||
Fut: Future<Output = Result<T, E>> + Send + 'static,
|
Fut: Future<Output = Result<T, E>> + Send + 'static,
|
||||||
T: Send + Sync + 'static,
|
T: Send + Sync + 'static,
|
||||||
@@ -434,9 +430,9 @@ where
|
|||||||
type Err = E;
|
type Err = E;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Context, F, Fut, T, E> Handler<Context> for FromFnAsync<F, Fut, T, E, (Context,)>
|
impl<Context, F, Fut, T, E> HandlerFor<Context> for FromFnAsync<F, Fut, T, E, (Context,)>
|
||||||
where
|
where
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
F: Fn(Context) -> Fut + Send + Sync + Clone + 'static,
|
F: Fn(Context) -> Fut + Send + Sync + Clone + 'static,
|
||||||
Fut: Future<Output = Result<T, E>> + Send + 'static,
|
Fut: Future<Output = Result<T, E>> + Send + 'static,
|
||||||
T: Send + Sync + 'static,
|
T: Send + Sync + 'static,
|
||||||
@@ -448,14 +444,14 @@ where
|
|||||||
) -> Result<Self::Ok, Self::Err> {
|
) -> Result<Self::Ok, Self::Err> {
|
||||||
(self.function)(handle_args.context).await
|
(self.function)(handle_args.context).await
|
||||||
}
|
}
|
||||||
fn metadata(&self, _: VecDeque<&'static str>, _: TypeId) -> OrdMap<&'static str, Value> {
|
fn metadata(&self, _: VecDeque<&'static str>) -> OrdMap<&'static str, Value> {
|
||||||
self.metadata.clone()
|
self.metadata.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Context, F, T, E, Params> HandlerTypes for FromFn<F, T, E, (Context, Params)>
|
impl<Context, F, T, E, Params> HandlerTypes for FromFn<F, T, E, (Context, Params)>
|
||||||
where
|
where
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
F: Fn(Context, Params) -> Result<T, E> + Send + Sync + Clone + 'static,
|
F: Fn(Context, Params) -> Result<T, E> + Send + Sync + Clone + 'static,
|
||||||
Params: DeserializeOwned + Send + Sync + 'static,
|
Params: DeserializeOwned + Send + Sync + 'static,
|
||||||
T: Send + Sync + 'static,
|
T: Send + Sync + 'static,
|
||||||
@@ -467,9 +463,9 @@ where
|
|||||||
type Err = E;
|
type Err = E;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Context, F, T, E, Params> Handler<Context> for FromFn<F, T, E, (Context, Params)>
|
impl<Context, F, T, E, Params> HandlerFor<Context> for FromFn<F, T, E, (Context, Params)>
|
||||||
where
|
where
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
F: Fn(Context, Params) -> Result<T, E> + Send + Sync + Clone + 'static,
|
F: Fn(Context, Params) -> Result<T, E> + Send + Sync + Clone + 'static,
|
||||||
Params: DeserializeOwned + Send + Sync + 'static,
|
Params: DeserializeOwned + Send + Sync + 'static,
|
||||||
T: Send + Sync + 'static,
|
T: Send + Sync + 'static,
|
||||||
@@ -494,13 +490,13 @@ where
|
|||||||
self.handle_async_with_sync(handle_args).await
|
self.handle_async_with_sync(handle_args).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn metadata(&self, _: VecDeque<&'static str>, _: TypeId) -> OrdMap<&'static str, Value> {
|
fn metadata(&self, _: VecDeque<&'static str>) -> OrdMap<&'static str, Value> {
|
||||||
self.metadata.clone()
|
self.metadata.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<Context, F, Fut, T, E, Params> HandlerTypes for FromFnAsync<F, Fut, T, E, (Context, Params)>
|
impl<Context, F, Fut, T, E, Params> HandlerTypes for FromFnAsync<F, Fut, T, E, (Context, Params)>
|
||||||
where
|
where
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
F: Fn(Context, Params) -> Fut + Send + Sync + Clone + 'static,
|
F: Fn(Context, Params) -> Fut + Send + Sync + Clone + 'static,
|
||||||
Fut: Future<Output = Result<T, E>> + Send + 'static,
|
Fut: Future<Output = Result<T, E>> + Send + 'static,
|
||||||
Params: DeserializeOwned + Send + Sync + 'static,
|
Params: DeserializeOwned + Send + Sync + 'static,
|
||||||
@@ -513,10 +509,10 @@ where
|
|||||||
type Err = E;
|
type Err = E;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Context, F, Fut, T, E, Params> Handler<Context>
|
impl<Context, F, Fut, T, E, Params> HandlerFor<Context>
|
||||||
for FromFnAsync<F, Fut, T, E, (Context, Params)>
|
for FromFnAsync<F, Fut, T, E, (Context, Params)>
|
||||||
where
|
where
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
F: Fn(Context, Params) -> Fut + Send + Sync + Clone + 'static,
|
F: Fn(Context, Params) -> Fut + Send + Sync + Clone + 'static,
|
||||||
Fut: Future<Output = Result<T, E>> + Send + 'static,
|
Fut: Future<Output = Result<T, E>> + Send + 'static,
|
||||||
Params: DeserializeOwned + Send + Sync + 'static,
|
Params: DeserializeOwned + Send + Sync + 'static,
|
||||||
@@ -532,7 +528,7 @@ where
|
|||||||
} = handle_args;
|
} = handle_args;
|
||||||
(self.function)(context, params).await
|
(self.function)(context, params).await
|
||||||
}
|
}
|
||||||
fn metadata(&self, _: VecDeque<&'static str>, _: TypeId) -> OrdMap<&'static str, Value> {
|
fn metadata(&self, _: VecDeque<&'static str>) -> OrdMap<&'static str, Value> {
|
||||||
self.metadata.clone()
|
self.metadata.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -540,7 +536,7 @@ where
|
|||||||
impl<Context, F, T, E, Params, InheritedParams> HandlerTypes
|
impl<Context, F, T, E, Params, InheritedParams> HandlerTypes
|
||||||
for FromFn<F, T, E, (Context, Params, InheritedParams)>
|
for FromFn<F, T, E, (Context, Params, InheritedParams)>
|
||||||
where
|
where
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
F: Fn(Context, Params, InheritedParams) -> Result<T, E> + Send + Sync + Clone + 'static,
|
F: Fn(Context, Params, InheritedParams) -> Result<T, E> + Send + Sync + Clone + 'static,
|
||||||
Params: DeserializeOwned + Send + Sync + 'static,
|
Params: DeserializeOwned + Send + Sync + 'static,
|
||||||
InheritedParams: Send + Sync + 'static,
|
InheritedParams: Send + Sync + 'static,
|
||||||
@@ -553,10 +549,10 @@ where
|
|||||||
type Err = E;
|
type Err = E;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Context, F, T, E, Params, InheritedParams> Handler<Context>
|
impl<Context, F, T, E, Params, InheritedParams> HandlerFor<Context>
|
||||||
for FromFn<F, T, E, (Context, Params, InheritedParams)>
|
for FromFn<F, T, E, (Context, Params, InheritedParams)>
|
||||||
where
|
where
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
F: Fn(Context, Params, InheritedParams) -> Result<T, E> + Send + Sync + Clone + 'static,
|
F: Fn(Context, Params, InheritedParams) -> Result<T, E> + Send + Sync + Clone + 'static,
|
||||||
Params: DeserializeOwned + Send + Sync + 'static,
|
Params: DeserializeOwned + Send + Sync + 'static,
|
||||||
InheritedParams: Send + Sync + 'static,
|
InheritedParams: Send + Sync + 'static,
|
||||||
@@ -585,14 +581,14 @@ where
|
|||||||
self.handle_async_with_sync(handle_args).await
|
self.handle_async_with_sync(handle_args).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn metadata(&self, _: VecDeque<&'static str>, _: TypeId) -> OrdMap<&'static str, Value> {
|
fn metadata(&self, _: VecDeque<&'static str>) -> OrdMap<&'static str, Value> {
|
||||||
self.metadata.clone()
|
self.metadata.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<Context, F, Fut, T, E, Params, InheritedParams> HandlerTypes
|
impl<Context, F, Fut, T, E, Params, InheritedParams> HandlerTypes
|
||||||
for FromFnAsync<F, Fut, T, E, (Context, Params, InheritedParams)>
|
for FromFnAsync<F, Fut, T, E, (Context, Params, InheritedParams)>
|
||||||
where
|
where
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
F: Fn(Context, Params, InheritedParams) -> Fut + Send + Sync + Clone + 'static,
|
F: Fn(Context, Params, InheritedParams) -> Fut + Send + Sync + Clone + 'static,
|
||||||
Fut: Future<Output = Result<T, E>> + Send + 'static,
|
Fut: Future<Output = Result<T, E>> + Send + 'static,
|
||||||
Params: DeserializeOwned + Send + Sync + 'static,
|
Params: DeserializeOwned + Send + Sync + 'static,
|
||||||
@@ -606,10 +602,10 @@ where
|
|||||||
type Err = E;
|
type Err = E;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Context, F, Fut, T, E, Params, InheritedParams> Handler<Context>
|
impl<Context, F, Fut, T, E, Params, InheritedParams> HandlerFor<Context>
|
||||||
for FromFnAsync<F, Fut, T, E, (Context, Params, InheritedParams)>
|
for FromFnAsync<F, Fut, T, E, (Context, Params, InheritedParams)>
|
||||||
where
|
where
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
F: Fn(Context, Params, InheritedParams) -> Fut + Send + Sync + Clone + 'static,
|
F: Fn(Context, Params, InheritedParams) -> Fut + Send + Sync + Clone + 'static,
|
||||||
Fut: Future<Output = Result<T, E>> + Send + 'static,
|
Fut: Future<Output = Result<T, E>> + Send + 'static,
|
||||||
Params: DeserializeOwned + Send + Sync + 'static,
|
Params: DeserializeOwned + Send + Sync + 'static,
|
||||||
@@ -629,7 +625,7 @@ where
|
|||||||
} = handle_args;
|
} = handle_args;
|
||||||
(self.function)(context, params, inherited_params).await
|
(self.function)(context, params, inherited_params).await
|
||||||
}
|
}
|
||||||
fn metadata(&self, _: VecDeque<&'static str>, _: TypeId) -> OrdMap<&'static str, Value> {
|
fn metadata(&self, _: VecDeque<&'static str>) -> OrdMap<&'static str, Value> {
|
||||||
self.metadata.clone()
|
self.metadata.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,13 +6,12 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use clap::{ArgMatches, Command, Parser};
|
use clap::{ArgMatches, Command, Parser};
|
||||||
use futures::Future;
|
use futures::Future;
|
||||||
use imbl_value::imbl::{OrdMap, OrdSet};
|
use imbl_value::imbl::OrdMap;
|
||||||
use imbl_value::Value;
|
use imbl_value::Value;
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use yajrc::RpcError;
|
use yajrc::RpcError;
|
||||||
|
|
||||||
use crate::context::{AnyContext, IntoContext};
|
|
||||||
use crate::util::{internal_error, invalid_params, Flat};
|
use crate::util::{internal_error, invalid_params, Flat};
|
||||||
|
|
||||||
pub mod adapters;
|
pub mod adapters;
|
||||||
@@ -23,19 +22,18 @@ pub use adapters::*;
|
|||||||
pub use from_fn::*;
|
pub use from_fn::*;
|
||||||
pub use parent::*;
|
pub use parent::*;
|
||||||
|
|
||||||
pub(crate) struct HandleAnyArgs<Inherited> {
|
pub(crate) struct HandleAnyArgs<Context, Inherited> {
|
||||||
pub(crate) context: AnyContext,
|
pub(crate) context: Context,
|
||||||
pub(crate) parent_method: VecDeque<&'static str>,
|
pub(crate) parent_method: VecDeque<&'static str>,
|
||||||
pub(crate) method: VecDeque<&'static str>,
|
pub(crate) method: VecDeque<&'static str>,
|
||||||
pub(crate) params: Value,
|
pub(crate) params: Value,
|
||||||
pub(crate) inherited: Inherited,
|
pub(crate) inherited: Inherited,
|
||||||
}
|
}
|
||||||
impl<Inherited: Send + Sync> HandleAnyArgs<Inherited> {
|
impl<Context: crate::Context, Inherited: Send + Sync> HandleAnyArgs<Context, Inherited> {
|
||||||
fn downcast<Context: IntoContext, H>(
|
fn downcast<H>(self) -> Result<HandlerArgsFor<Context, H>, imbl_value::Error>
|
||||||
self,
|
|
||||||
) -> Result<HandlerArgsFor<Context, H>, imbl_value::Error>
|
|
||||||
where
|
where
|
||||||
H: HandlerTypes<InheritedParams = Inherited>,
|
H: HandlerTypes,
|
||||||
|
H::InheritedParams: OrEmpty<Inherited>,
|
||||||
H::Params: DeserializeOwned,
|
H::Params: DeserializeOwned,
|
||||||
{
|
{
|
||||||
let Self {
|
let Self {
|
||||||
@@ -46,84 +44,77 @@ impl<Inherited: Send + Sync> HandleAnyArgs<Inherited> {
|
|||||||
inherited,
|
inherited,
|
||||||
} = self;
|
} = self;
|
||||||
Ok(HandlerArgs {
|
Ok(HandlerArgs {
|
||||||
context: Context::downcast(context).map_err(|_| imbl_value::Error {
|
context,
|
||||||
kind: imbl_value::ErrorKind::Deserialization,
|
|
||||||
source: serde::ser::Error::custom("context does not match expected"),
|
|
||||||
})?,
|
|
||||||
parent_method,
|
parent_method,
|
||||||
method,
|
method,
|
||||||
params: imbl_value::from_value(params.clone())?,
|
params: imbl_value::from_value(params.clone())?,
|
||||||
inherited_params: inherited,
|
inherited_params: OrEmpty::from_t(inherited),
|
||||||
raw_params: params,
|
raw_params: params,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
pub(crate) trait HandleAny: Send + Sync {
|
pub(crate) trait HandleAny<Context>: Send + Sync {
|
||||||
type Inherited: Send;
|
type Inherited: Send;
|
||||||
fn handle_sync(&self, handle_args: HandleAnyArgs<Self::Inherited>) -> Result<Value, RpcError>;
|
fn handle_sync(
|
||||||
|
&self,
|
||||||
|
handle_args: HandleAnyArgs<Context, Self::Inherited>,
|
||||||
|
) -> Result<Value, RpcError>;
|
||||||
async fn handle_async(
|
async fn handle_async(
|
||||||
&self,
|
&self,
|
||||||
handle_args: HandleAnyArgs<Self::Inherited>,
|
handle_args: HandleAnyArgs<Context, Self::Inherited>,
|
||||||
) -> Result<Value, RpcError>;
|
) -> Result<Value, RpcError>;
|
||||||
fn metadata(
|
fn metadata(&self, method: VecDeque<&'static str>) -> OrdMap<&'static str, Value>;
|
||||||
&self,
|
fn method_from_dots(&self, method: &str) -> Option<VecDeque<&'static str>>;
|
||||||
method: VecDeque<&'static str>,
|
fn cli(&self) -> Option<&dyn CliBindingsAny<Context, Inherited = Self::Inherited>>;
|
||||||
ctx_ty: TypeId,
|
|
||||||
) -> OrdMap<&'static str, Value>;
|
|
||||||
fn method_from_dots(&self, method: &str, ctx_ty: TypeId) -> Option<VecDeque<&'static str>>;
|
|
||||||
fn cli(&self) -> Option<&dyn CliBindingsAny<Inherited = Self::Inherited>>;
|
|
||||||
}
|
}
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl<T: HandleAny> HandleAny for Arc<T> {
|
impl<Context: crate::Context, T: HandleAny<Context>> HandleAny<Context> for Arc<T> {
|
||||||
type Inherited = T::Inherited;
|
type Inherited = T::Inherited;
|
||||||
fn handle_sync(&self, handle_args: HandleAnyArgs<Self::Inherited>) -> Result<Value, RpcError> {
|
fn handle_sync(
|
||||||
|
&self,
|
||||||
|
handle_args: HandleAnyArgs<Context, Self::Inherited>,
|
||||||
|
) -> Result<Value, RpcError> {
|
||||||
self.deref().handle_sync(handle_args)
|
self.deref().handle_sync(handle_args)
|
||||||
}
|
}
|
||||||
async fn handle_async(
|
async fn handle_async(
|
||||||
&self,
|
&self,
|
||||||
handle_args: HandleAnyArgs<Self::Inherited>,
|
handle_args: HandleAnyArgs<Context, Self::Inherited>,
|
||||||
) -> Result<Value, RpcError> {
|
) -> Result<Value, RpcError> {
|
||||||
self.deref().handle_async(handle_args).await
|
self.deref().handle_async(handle_args).await
|
||||||
}
|
}
|
||||||
fn metadata(
|
fn metadata(&self, method: VecDeque<&'static str>) -> OrdMap<&'static str, Value> {
|
||||||
&self,
|
self.deref().metadata(method)
|
||||||
method: VecDeque<&'static str>,
|
|
||||||
ctx_ty: TypeId,
|
|
||||||
) -> OrdMap<&'static str, Value> {
|
|
||||||
self.deref().metadata(method, ctx_ty)
|
|
||||||
}
|
}
|
||||||
fn method_from_dots(&self, method: &str, ctx_ty: TypeId) -> Option<VecDeque<&'static str>> {
|
fn method_from_dots(&self, method: &str) -> Option<VecDeque<&'static str>> {
|
||||||
self.deref().method_from_dots(method, ctx_ty)
|
self.deref().method_from_dots(method)
|
||||||
}
|
}
|
||||||
fn cli(&self) -> Option<&dyn CliBindingsAny<Inherited = Self::Inherited>> {
|
fn cli(&self) -> Option<&dyn CliBindingsAny<Context, Inherited = Self::Inherited>> {
|
||||||
self.deref().cli()
|
self.deref().cli()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) trait CliBindingsAny {
|
pub(crate) trait CliBindingsAny<Context> {
|
||||||
type Inherited;
|
type Inherited;
|
||||||
fn cli_command(&self, ctx_ty: TypeId) -> Command;
|
fn cli_command(&self) -> Command;
|
||||||
fn cli_parse(
|
fn cli_parse(
|
||||||
&self,
|
&self,
|
||||||
matches: &ArgMatches,
|
matches: &ArgMatches,
|
||||||
ctx_ty: TypeId,
|
|
||||||
) -> Result<(VecDeque<&'static str>, Value), clap::Error>;
|
) -> Result<(VecDeque<&'static str>, Value), clap::Error>;
|
||||||
fn cli_display(
|
fn cli_display(
|
||||||
&self,
|
&self,
|
||||||
handle_args: HandleAnyArgs<Self::Inherited>,
|
handle_args: HandleAnyArgs<Context, Self::Inherited>,
|
||||||
result: Value,
|
result: Value,
|
||||||
) -> Result<(), RpcError>;
|
) -> Result<(), RpcError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait CliBindings<Context: IntoContext>: HandlerTypes {
|
pub trait CliBindings<Context: crate::Context>: HandlerTypes {
|
||||||
const NO_CLI: bool = false;
|
const NO_CLI: bool = false;
|
||||||
fn cli_command(&self, ctx_ty: TypeId) -> Command;
|
fn cli_command(&self) -> Command;
|
||||||
fn cli_parse(
|
fn cli_parse(
|
||||||
&self,
|
&self,
|
||||||
matches: &ArgMatches,
|
matches: &ArgMatches,
|
||||||
ctx_ty: TypeId,
|
|
||||||
) -> Result<(VecDeque<&'static str>, Value), clap::Error>;
|
) -> Result<(VecDeque<&'static str>, Value), clap::Error>;
|
||||||
fn cli_display(
|
fn cli_display(
|
||||||
&self,
|
&self,
|
||||||
@@ -132,7 +123,7 @@ pub trait CliBindings<Context: IntoContext>: HandlerTypes {
|
|||||||
) -> Result<(), Self::Err>;
|
) -> Result<(), Self::Err>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait PrintCliResult<Context: IntoContext>: HandlerTypes {
|
pub trait PrintCliResult<Context: crate::Context>: HandlerTypes {
|
||||||
fn print(
|
fn print(
|
||||||
&self,
|
&self,
|
||||||
handle_args: HandlerArgsFor<Context, Self>,
|
handle_args: HandlerArgsFor<Context, Self>,
|
||||||
@@ -141,53 +132,56 @@ pub trait PrintCliResult<Context: IntoContext>: HandlerTypes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(private_interfaces)]
|
#[allow(private_interfaces)]
|
||||||
pub struct DynHandler<Inherited>(Arc<dyn HandleAny<Inherited = Inherited>>);
|
pub struct DynHandler<Context, Inherited>(Arc<dyn HandleAny<Context, Inherited = Inherited>>);
|
||||||
impl<Inherited> DynHandler<Inherited> {
|
impl<Context: crate::Context, Inherited> DynHandler<Context, Inherited> {
|
||||||
pub fn iter<C: IntoContext, H: Handler<C> + CliBindings<C>>(
|
pub fn new<C, H>(handler: H) -> Option<Self>
|
||||||
h: H,
|
where
|
||||||
) -> Option<impl IntoIterator<Item = (Option<TypeId>, Self)>> {
|
C: crate::Context,
|
||||||
iter_from_ctx_and_handler(ctx, handler)
|
WithContext<C, H>: Handler<Inherited>,
|
||||||
|
{
|
||||||
|
WithContext::<C, _>::new(handler).handler_for::<Context>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<Inherited> Clone for DynHandler<Inherited> {
|
impl<Context, Inherited> Clone for DynHandler<Context, Inherited> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self(self.0.clone())
|
Self(self.0.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl<Inherited: Send> HandleAny for DynHandler<Inherited> {
|
impl<Context: crate::Context, Inherited: Send> HandleAny<Context>
|
||||||
|
for DynHandler<Context, Inherited>
|
||||||
|
{
|
||||||
type Inherited = Inherited;
|
type Inherited = Inherited;
|
||||||
fn handle_sync(&self, handle_args: HandleAnyArgs<Self::Inherited>) -> Result<Value, RpcError> {
|
fn handle_sync(
|
||||||
|
&self,
|
||||||
|
handle_args: HandleAnyArgs<Context, Self::Inherited>,
|
||||||
|
) -> Result<Value, RpcError> {
|
||||||
self.0.handle_sync(handle_args)
|
self.0.handle_sync(handle_args)
|
||||||
}
|
}
|
||||||
async fn handle_async(
|
async fn handle_async(
|
||||||
&self,
|
&self,
|
||||||
handle_args: HandleAnyArgs<Self::Inherited>,
|
handle_args: HandleAnyArgs<Context, Self::Inherited>,
|
||||||
) -> Result<Value, RpcError> {
|
) -> Result<Value, RpcError> {
|
||||||
self.0.handle_async(handle_args).await
|
self.0.handle_async(handle_args).await
|
||||||
}
|
}
|
||||||
fn metadata(
|
fn metadata(&self, method: VecDeque<&'static str>) -> OrdMap<&'static str, Value> {
|
||||||
&self,
|
self.0.metadata(method)
|
||||||
method: VecDeque<&'static str>,
|
|
||||||
ctx_ty: TypeId,
|
|
||||||
) -> OrdMap<&'static str, Value> {
|
|
||||||
self.0.metadata(method, ctx_ty)
|
|
||||||
}
|
}
|
||||||
fn method_from_dots(&self, method: &str, ctx_ty: TypeId) -> Option<VecDeque<&'static str>> {
|
fn method_from_dots(&self, method: &str) -> Option<VecDeque<&'static str>> {
|
||||||
self.0.method_from_dots(method, ctx_ty)
|
self.0.method_from_dots(method)
|
||||||
}
|
}
|
||||||
fn cli(&self) -> Option<&dyn CliBindingsAny<Inherited = Self::Inherited>> {
|
fn cli(&self) -> Option<&dyn CliBindingsAny<Context, Inherited = Self::Inherited>> {
|
||||||
self.0.cli()
|
self.0.cli()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(type_alias_bounds)]
|
#[allow(type_alias_bounds)]
|
||||||
pub type HandlerArgsFor<Context: IntoContext, H: HandlerTypes + ?Sized> =
|
pub type HandlerArgsFor<Context: crate::Context, H: HandlerTypes + ?Sized> =
|
||||||
HandlerArgs<Context, H::Params, H::InheritedParams>;
|
HandlerArgs<Context, H::Params, H::InheritedParams>;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct HandlerArgs<
|
pub struct HandlerArgs<
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
Params: Send + Sync = Empty,
|
Params: Send + Sync = Empty,
|
||||||
InheritedParams: Send + Sync = Empty,
|
InheritedParams: Send + Sync = Empty,
|
||||||
> {
|
> {
|
||||||
@@ -206,7 +200,9 @@ pub trait HandlerTypes {
|
|||||||
type Err: Send + Sync;
|
type Err: Send + Sync;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Handler<Context: IntoContext>: HandlerTypes + Clone + Send + Sync + 'static {
|
pub trait HandlerFor<Context: crate::Context>:
|
||||||
|
HandlerTypes + Clone + Send + Sync + 'static
|
||||||
|
{
|
||||||
fn handle_sync(
|
fn handle_sync(
|
||||||
&self,
|
&self,
|
||||||
handle_args: HandlerArgsFor<Context, Self>,
|
handle_args: HandlerArgsFor<Context, Self>,
|
||||||
@@ -241,18 +237,11 @@ pub trait Handler<Context: IntoContext>: HandlerTypes + Clone + Send + Sync + 's
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
fn metadata(
|
fn metadata(&self, method: VecDeque<&'static str>) -> OrdMap<&'static str, Value> {
|
||||||
&self,
|
|
||||||
method: VecDeque<&'static str>,
|
|
||||||
ctx_ty: TypeId,
|
|
||||||
) -> OrdMap<&'static str, Value> {
|
|
||||||
OrdMap::new()
|
OrdMap::new()
|
||||||
}
|
}
|
||||||
fn contexts(&self) -> Option<OrdSet<TypeId>> {
|
|
||||||
Context::type_ids()
|
|
||||||
}
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
fn method_from_dots(&self, method: &str, ctx_ty: TypeId) -> Option<VecDeque<&'static str>> {
|
fn method_from_dots(&self, method: &str) -> Option<VecDeque<&'static str>> {
|
||||||
if method.is_empty() {
|
if method.is_empty() {
|
||||||
Some(VecDeque::new())
|
Some(VecDeque::new())
|
||||||
} else {
|
} else {
|
||||||
@@ -261,11 +250,53 @@ pub trait Handler<Context: IntoContext>: HandlerTypes + Clone + Send + Sync + 's
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct AnyHandler<Context, H> {
|
pub trait Handler<Inherited> {
|
||||||
|
type H: HandlerTypes;
|
||||||
|
fn handler_for<C: crate::Context>(self) -> Option<DynHandler<C, Inherited>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct WithContext<Context, H> {
|
||||||
_phantom: PhantomData<Context>,
|
_phantom: PhantomData<Context>,
|
||||||
handler: H,
|
handler: H,
|
||||||
}
|
}
|
||||||
impl<Context, H> AnyHandler<Context, H> {
|
impl<Context, H> WithContext<Context, H> {
|
||||||
|
pub fn new(handler: H) -> Self {
|
||||||
|
Self {
|
||||||
|
_phantom: PhantomData,
|
||||||
|
handler,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Context, Inherited, H> Handler<Inherited> for WithContext<Context, H>
|
||||||
|
where
|
||||||
|
Context: crate::Context,
|
||||||
|
H: HandlerFor<Context> + CliBindings<Context>,
|
||||||
|
H::Ok: Serialize + DeserializeOwned,
|
||||||
|
H::Params: DeserializeOwned,
|
||||||
|
H::InheritedParams: OrEmpty<Inherited>,
|
||||||
|
RpcError: From<H::Err>,
|
||||||
|
Inherited: Send + Sync + 'static,
|
||||||
|
{
|
||||||
|
type H = H;
|
||||||
|
fn handler_for<C: crate::Context>(self) -> Option<DynHandler<C, Inherited>> {
|
||||||
|
if TypeId::of::<Context>() == TypeId::of::<C>() {
|
||||||
|
Some(unsafe {
|
||||||
|
std::mem::transmute::<DynHandler<Context, Inherited>, DynHandler<C, Inherited>>(
|
||||||
|
DynHandler(Arc::new(AnyHandler::new(self.handler))),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) struct AnyHandler<Context, Inherited, H> {
|
||||||
|
_phantom: PhantomData<(Context, Inherited)>,
|
||||||
|
handler: H,
|
||||||
|
}
|
||||||
|
impl<Context, Inherited, H> AnyHandler<Context, Inherited, H> {
|
||||||
pub(crate) fn new(handler: H) -> Self {
|
pub(crate) fn new(handler: H) -> Self {
|
||||||
Self {
|
Self {
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
@@ -273,7 +304,7 @@ impl<Context, H> AnyHandler<Context, H> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<Context, H: std::fmt::Debug> std::fmt::Debug for AnyHandler<Context, H> {
|
impl<Context, Inherited, H: std::fmt::Debug> std::fmt::Debug for AnyHandler<Context, Inherited, 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_struct("AnyHandler")
|
f.debug_struct("AnyHandler")
|
||||||
.field("handler", &self.handler)
|
.field("handler", &self.handler)
|
||||||
@@ -282,46 +313,47 @@ impl<Context, H: std::fmt::Debug> std::fmt::Debug for AnyHandler<Context, H> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl<Context, H> HandleAny for AnyHandler<Context, H>
|
impl<Context, Inherited, H> HandleAny<Context> for AnyHandler<Context, Inherited, H>
|
||||||
where
|
where
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
H: Handler<Context> + CliBindings<Context>,
|
H: HandlerFor<Context> + CliBindings<Context>,
|
||||||
H::Params: DeserializeOwned,
|
H::Params: DeserializeOwned,
|
||||||
H::Ok: Serialize + DeserializeOwned,
|
H::Ok: Serialize + DeserializeOwned,
|
||||||
|
H::InheritedParams: OrEmpty<Inherited>,
|
||||||
RpcError: From<H::Err>,
|
RpcError: From<H::Err>,
|
||||||
|
Inherited: Send + Sync,
|
||||||
{
|
{
|
||||||
type Inherited = H::InheritedParams;
|
type Inherited = Inherited;
|
||||||
fn handle_sync(&self, handle_args: HandleAnyArgs<Self::Inherited>) -> Result<Value, RpcError> {
|
fn handle_sync(
|
||||||
|
&self,
|
||||||
|
handle_args: HandleAnyArgs<Context, Self::Inherited>,
|
||||||
|
) -> Result<Value, RpcError> {
|
||||||
imbl_value::to_value(
|
imbl_value::to_value(
|
||||||
&self
|
&self
|
||||||
.handler
|
.handler
|
||||||
.handle_sync(handle_args.downcast::<_, H>().map_err(invalid_params)?)?,
|
.handle_sync(handle_args.downcast::<H>().map_err(invalid_params)?)?,
|
||||||
)
|
)
|
||||||
.map_err(internal_error)
|
.map_err(internal_error)
|
||||||
}
|
}
|
||||||
async fn handle_async(
|
async fn handle_async(
|
||||||
&self,
|
&self,
|
||||||
handle_args: HandleAnyArgs<Self::Inherited>,
|
handle_args: HandleAnyArgs<Context, Self::Inherited>,
|
||||||
) -> Result<Value, RpcError> {
|
) -> Result<Value, RpcError> {
|
||||||
imbl_value::to_value(
|
imbl_value::to_value(
|
||||||
&self
|
&self
|
||||||
.handler
|
.handler
|
||||||
.handle_async(handle_args.downcast::<_, H>().map_err(invalid_params)?)
|
.handle_async(handle_args.downcast::<H>().map_err(invalid_params)?)
|
||||||
.await?,
|
.await?,
|
||||||
)
|
)
|
||||||
.map_err(internal_error)
|
.map_err(internal_error)
|
||||||
}
|
}
|
||||||
fn metadata(
|
fn metadata(&self, method: VecDeque<&'static str>) -> OrdMap<&'static str, Value> {
|
||||||
&self,
|
self.handler.metadata(method)
|
||||||
method: VecDeque<&'static str>,
|
|
||||||
ctx_ty: TypeId,
|
|
||||||
) -> OrdMap<&'static str, Value> {
|
|
||||||
self.handler.metadata(method, ctx_ty)
|
|
||||||
}
|
}
|
||||||
fn method_from_dots(&self, method: &str, ctx_ty: TypeId) -> Option<VecDeque<&'static str>> {
|
fn method_from_dots(&self, method: &str) -> Option<VecDeque<&'static str>> {
|
||||||
self.handler.method_from_dots(method, ctx_ty)
|
self.handler.method_from_dots(method)
|
||||||
}
|
}
|
||||||
fn cli(&self) -> Option<&dyn CliBindingsAny<Inherited = Self::Inherited>> {
|
fn cli(&self) -> Option<&dyn CliBindingsAny<Context, Inherited = Self::Inherited>> {
|
||||||
if H::NO_CLI {
|
if H::NO_CLI {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
@@ -330,33 +362,34 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Context, H> CliBindingsAny for AnyHandler<Context, H>
|
impl<Context, Inherited, H> CliBindingsAny<Context> for AnyHandler<Context, Inherited, H>
|
||||||
where
|
where
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
H: CliBindings<Context>,
|
H: CliBindings<Context>,
|
||||||
H::Params: DeserializeOwned,
|
H::Params: DeserializeOwned,
|
||||||
H::Ok: Serialize + DeserializeOwned,
|
H::Ok: Serialize + DeserializeOwned,
|
||||||
RpcError: From<H::Err>,
|
RpcError: From<H::Err>,
|
||||||
|
H::InheritedParams: OrEmpty<Inherited>,
|
||||||
|
Inherited: Send + Sync,
|
||||||
{
|
{
|
||||||
type Inherited = H::InheritedParams;
|
type Inherited = Inherited;
|
||||||
fn cli_command(&self, ctx_ty: TypeId) -> Command {
|
fn cli_command(&self) -> Command {
|
||||||
self.handler.cli_command(ctx_ty)
|
self.handler.cli_command()
|
||||||
}
|
}
|
||||||
fn cli_parse(
|
fn cli_parse(
|
||||||
&self,
|
&self,
|
||||||
matches: &ArgMatches,
|
matches: &ArgMatches,
|
||||||
ctx_ty: TypeId,
|
|
||||||
) -> Result<(VecDeque<&'static str>, Value), clap::Error> {
|
) -> Result<(VecDeque<&'static str>, Value), clap::Error> {
|
||||||
self.handler.cli_parse(matches, ctx_ty)
|
self.handler.cli_parse(matches)
|
||||||
}
|
}
|
||||||
fn cli_display(
|
fn cli_display(
|
||||||
&self,
|
&self,
|
||||||
handle_args: HandleAnyArgs<Self::Inherited>,
|
handle_args: HandleAnyArgs<Context, Self::Inherited>,
|
||||||
result: Value,
|
result: Value,
|
||||||
) -> Result<(), RpcError> {
|
) -> Result<(), RpcError> {
|
||||||
self.handler
|
self.handler
|
||||||
.cli_display(
|
.cli_display(
|
||||||
handle_args.downcast::<_, H>().map_err(invalid_params)?,
|
handle_args.downcast::<H>().map_err(invalid_params)?,
|
||||||
imbl_value::from_value(result).map_err(internal_error)?,
|
imbl_value::from_value(result).map_err(internal_error)?,
|
||||||
)
|
)
|
||||||
.map_err(RpcError::from)
|
.map_err(RpcError::from)
|
||||||
@@ -375,7 +408,7 @@ impl<T> OrEmpty<T> for T {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<A, B> OrEmpty<Flat<A, B>> for Empty {
|
impl<A, B> OrEmpty<Flat<A, B>> for Empty {
|
||||||
fn from_t(t: Flat<A, B>) -> Self {
|
fn from_t(_: Flat<A, B>) -> Self {
|
||||||
Empty {}
|
Empty {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,42 +1,17 @@
|
|||||||
use std::any::TypeId;
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
use clap::{ArgMatches, Command, CommandFactory, FromArgMatches};
|
use clap::{ArgMatches, Command, CommandFactory, FromArgMatches};
|
||||||
use imbl_value::imbl::{OrdMap, OrdSet};
|
use imbl_value::imbl::OrdMap;
|
||||||
use imbl_value::Value;
|
use imbl_value::Value;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use yajrc::RpcError;
|
use yajrc::RpcError;
|
||||||
|
|
||||||
use crate::util::{combine, Flat, PhantomData};
|
use crate::util::{combine, Flat, PhantomData};
|
||||||
use crate::{
|
use crate::{
|
||||||
AnyContext, CliBindings, DynHandler, Empty, HandleAny, HandleAnyArgs, Handler, HandlerArgs,
|
CliBindings, DynHandler, Empty, HandleAny, HandleAnyArgs, Handler, HandlerArgs, HandlerArgsFor,
|
||||||
HandlerArgsFor, HandlerTypes, IntoContext,
|
HandlerFor, HandlerTypes, WithContext,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) fn iter_from_ctx_and_handler<Inherited>(
|
|
||||||
ctx: Option<OrdSet<TypeId>>,
|
|
||||||
handler: DynHandler<Inherited>,
|
|
||||||
) -> impl IntoIterator<Item = (Option<TypeId>, DynHandler<Inherited>)> {
|
|
||||||
if let Some(ctx) = ctx {
|
|
||||||
itertools::Either::Left(ctx.into_iter().map(Some))
|
|
||||||
} else {
|
|
||||||
itertools::Either::Right(std::iter::once(None))
|
|
||||||
}
|
|
||||||
.map(move |ctx| (ctx, handler.clone()))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn intersect_type_ids(
|
|
||||||
a: Option<OrdSet<TypeId>>,
|
|
||||||
b: Option<OrdSet<TypeId>>,
|
|
||||||
) -> Option<OrdSet<TypeId>> {
|
|
||||||
match (a, b) {
|
|
||||||
(None, None) => None,
|
|
||||||
(Some(a), None) => Some(a),
|
|
||||||
(None, Some(b)) => Some(b),
|
|
||||||
(Some(a), Some(b)) => Some(a.intersection(b)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub(crate) struct Name(pub(crate) Option<&'static str>);
|
pub(crate) struct Name(pub(crate) Option<&'static str>);
|
||||||
impl<'a> std::borrow::Borrow<Option<&'a str>> for Name {
|
impl<'a> std::borrow::Borrow<Option<&'a str>> for Name {
|
||||||
@@ -45,47 +20,30 @@ impl<'a> std::borrow::Borrow<Option<&'a str>> for Name {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct SubcommandMap<Inherited>(
|
pub(crate) struct SubcommandMap<Context, Inherited>(
|
||||||
pub(crate) OrdMap<Name, OrdMap<Option<TypeId>, DynHandler<Inherited>>>,
|
pub(crate) OrdMap<Name, DynHandler<Context, Inherited>>,
|
||||||
);
|
);
|
||||||
impl<Inherited> Clone for SubcommandMap<Inherited> {
|
impl<Context, Inherited> Clone for SubcommandMap<Context, Inherited> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self(self.0.clone())
|
Self(self.0.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<Inherited> SubcommandMap<Inherited> {
|
impl<Context, Inherited> SubcommandMap<Context, Inherited> {
|
||||||
fn insert(
|
fn insert(&mut self, name: Option<&'static str>, handler: DynHandler<Context, Inherited>) {
|
||||||
&mut self,
|
self.0.insert(Name(name), handler);
|
||||||
name: Option<&'static str>,
|
|
||||||
handlers: impl IntoIterator<Item = (Option<TypeId>, DynHandler<Inherited>)>,
|
|
||||||
) {
|
|
||||||
let mut for_name = self.0.remove(&name).unwrap_or_default();
|
|
||||||
for (ctx_ty, handler) in handlers {
|
|
||||||
for_name.insert(ctx_ty, handler);
|
|
||||||
}
|
|
||||||
self.0.insert(Name(name), for_name);
|
|
||||||
}
|
}
|
||||||
|
fn get<'a>(&'a self, name: Option<&str>) -> Option<(Name, &'a DynHandler<Context, Inherited>)> {
|
||||||
fn get<'a>(
|
if let Some((name, handler)) = self.0.get_key_value(&name) {
|
||||||
&'a self,
|
Some((*name, handler))
|
||||||
ctx_ty: TypeId,
|
|
||||||
name: Option<&str>,
|
|
||||||
) -> Option<(Name, &'a DynHandler<Inherited>)> {
|
|
||||||
if let Some((name, for_name)) = self.0.get_key_value(&name) {
|
|
||||||
if let Some(for_ctx) = for_name.get(&Some(ctx_ty)) {
|
|
||||||
Some((*name, for_ctx))
|
|
||||||
} else {
|
|
||||||
for_name.get(&None).map(|h| (*name, h))
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ParentHandler<Context = AnyContext, Params = Empty, InheritedParams = Empty> {
|
pub struct ParentHandler<Context, Params = Empty, InheritedParams = Empty> {
|
||||||
_phantom: PhantomData<Context>,
|
_phantom: PhantomData<Context>,
|
||||||
pub(crate) subcommands: SubcommandMap<Flat<Params, InheritedParams>>,
|
pub(crate) subcommands: SubcommandMap<Context, Flat<Params, InheritedParams>>,
|
||||||
metadata: OrdMap<&'static str, Value>,
|
metadata: OrdMap<&'static str, Value>,
|
||||||
}
|
}
|
||||||
impl<Context, Params, InheritedParams> ParentHandler<Context, Params, InheritedParams> {
|
impl<Context, Params, InheritedParams> ParentHandler<Context, Params, InheritedParams> {
|
||||||
@@ -120,33 +78,25 @@ impl<Context, Params, InheritedParams> std::fmt::Debug
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Context: IntoContext, Params, InheritedParams>
|
impl<Context: crate::Context, Params, InheritedParams>
|
||||||
ParentHandler<Context, Params, InheritedParams>
|
ParentHandler<Context, Params, InheritedParams>
|
||||||
{
|
{
|
||||||
fn get_contexts(&self) -> Option<OrdSet<TypeId>> {
|
pub fn subcommand<C: crate::Context, H>(mut self, name: &'static str, handler: H) -> Self
|
||||||
let mut set = OrdSet::new();
|
|
||||||
for ctx_ty in self.subcommands.0.values().flat_map(|c| c.keys()) {
|
|
||||||
set.insert((*ctx_ty)?);
|
|
||||||
}
|
|
||||||
Some(set)
|
|
||||||
}
|
|
||||||
#[allow(private_bounds)]
|
|
||||||
pub fn subcommand<C: IntoContext, H>(mut self, name: &'static str, handler: H) -> Self
|
|
||||||
where
|
where
|
||||||
H: Handler<C, InheritedParams = Flat<Params, InheritedParams>> + CliBindings<C>,
|
WithContext<C, H>: Handler<Flat<Params, InheritedParams>>,
|
||||||
{
|
{
|
||||||
if let Some(h) = DynHandler::iter(handler) {
|
if let Some(h) = DynHandler::new(handler) {
|
||||||
self.subcommands.insert(name.into(), h);
|
self.subcommands.insert(name.into(), h);
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
#[allow(private_bounds)]
|
pub fn root_handler<C: crate::Context, H>(mut self, handler: H) -> Self
|
||||||
pub fn root_handler<C: IntoContext, H>(mut self, handler: H) -> Self
|
|
||||||
where
|
where
|
||||||
H: Handler<C, Params = Empty, InheritedParams = Flat<Params, InheritedParams>>
|
WithContext<C, H>: Handler<Flat<Params, InheritedParams>>,
|
||||||
+ CliBindings<C>,
|
<WithContext<C, H> as Handler<Flat<Params, InheritedParams>>>::H:
|
||||||
|
HandlerTypes<Params = Empty>,
|
||||||
{
|
{
|
||||||
if let Some((c, h)) = DynHandler::iter(handler) {
|
if let Some(h) = DynHandler::new(handler) {
|
||||||
self.subcommands.insert(None, h);
|
self.subcommands.insert(None, h);
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
@@ -165,10 +115,10 @@ where
|
|||||||
type Err = RpcError;
|
type Err = RpcError;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Context, Params, InheritedParams> Handler<Context>
|
impl<Context, Params, InheritedParams> HandlerFor<Context>
|
||||||
for ParentHandler<Context, Params, InheritedParams>
|
for ParentHandler<Context, Params, InheritedParams>
|
||||||
where
|
where
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
Params: Send + Sync + 'static,
|
Params: Send + Sync + 'static,
|
||||||
InheritedParams: Serialize + Send + Sync + 'static,
|
InheritedParams: Serialize + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
@@ -187,9 +137,9 @@ where
|
|||||||
if let Some(cmd) = cmd {
|
if let Some(cmd) = cmd {
|
||||||
parent_method.push_back(cmd);
|
parent_method.push_back(cmd);
|
||||||
}
|
}
|
||||||
if let Some((_, sub_handler)) = &self.subcommands.get(context.inner_type_id(), cmd) {
|
if let Some((_, sub_handler)) = &self.subcommands.get(cmd) {
|
||||||
sub_handler.handle_sync(HandleAnyArgs {
|
sub_handler.handle_sync(HandleAnyArgs {
|
||||||
context: context.upcast(),
|
context,
|
||||||
parent_method,
|
parent_method,
|
||||||
method,
|
method,
|
||||||
params: raw_params,
|
params: raw_params,
|
||||||
@@ -214,10 +164,10 @@ where
|
|||||||
if let Some(cmd) = cmd {
|
if let Some(cmd) = cmd {
|
||||||
parent_method.push_back(cmd);
|
parent_method.push_back(cmd);
|
||||||
}
|
}
|
||||||
if let Some((_, sub_handler)) = self.subcommands.get(context.inner_type_id(), cmd) {
|
if let Some((_, sub_handler)) = self.subcommands.get(cmd) {
|
||||||
sub_handler
|
sub_handler
|
||||||
.handle_async(HandleAnyArgs {
|
.handle_async(HandleAnyArgs {
|
||||||
context: context.upcast(),
|
context,
|
||||||
parent_method,
|
parent_method,
|
||||||
method,
|
method,
|
||||||
params: raw_params,
|
params: raw_params,
|
||||||
@@ -228,22 +178,15 @@ where
|
|||||||
Err(yajrc::METHOD_NOT_FOUND_ERROR)
|
Err(yajrc::METHOD_NOT_FOUND_ERROR)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn metadata(
|
fn metadata(&self, mut method: VecDeque<&'static str>) -> OrdMap<&'static str, Value> {
|
||||||
&self,
|
|
||||||
mut method: VecDeque<&'static str>,
|
|
||||||
ctx_ty: TypeId,
|
|
||||||
) -> OrdMap<&'static str, Value> {
|
|
||||||
let metadata = self.metadata.clone();
|
let metadata = self.metadata.clone();
|
||||||
if let Some((_, handler)) = self.subcommands.get(ctx_ty, method.pop_front()) {
|
if let Some((_, handler)) = self.subcommands.get(method.pop_front()) {
|
||||||
handler.metadata(method, ctx_ty).union(metadata)
|
handler.metadata(method).union(metadata)
|
||||||
} else {
|
} else {
|
||||||
metadata
|
metadata
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn contexts(&self) -> Option<OrdSet<TypeId>> {
|
fn method_from_dots(&self, method: &str) -> Option<VecDeque<&'static str>> {
|
||||||
self.get_contexts()
|
|
||||||
}
|
|
||||||
fn method_from_dots(&self, method: &str, ctx_ty: TypeId) -> Option<VecDeque<&'static str>> {
|
|
||||||
let (head, tail) = if method.is_empty() {
|
let (head, tail) = if method.is_empty() {
|
||||||
(None, None)
|
(None, None)
|
||||||
} else {
|
} else {
|
||||||
@@ -252,13 +195,13 @@ where
|
|||||||
.map(|(head, tail)| (Some(head), Some(tail)))
|
.map(|(head, tail)| (Some(head), Some(tail)))
|
||||||
.unwrap_or((Some(method), None))
|
.unwrap_or((Some(method), None))
|
||||||
};
|
};
|
||||||
let (Name(name), h) = self.subcommands.get(ctx_ty, head)?;
|
let (Name(name), h) = self.subcommands.get(head)?;
|
||||||
let mut res = VecDeque::new();
|
let mut res = VecDeque::new();
|
||||||
if let Some(name) = name {
|
if let Some(name) = name {
|
||||||
res.push_back(name);
|
res.push_back(name);
|
||||||
}
|
}
|
||||||
if let Some(tail) = tail {
|
if let Some(tail) = tail {
|
||||||
res.append(&mut h.method_from_dots(tail, ctx_ty)?);
|
res.append(&mut h.method_from_dots(tail)?);
|
||||||
}
|
}
|
||||||
Some(res)
|
Some(res)
|
||||||
}
|
}
|
||||||
@@ -267,25 +210,16 @@ where
|
|||||||
impl<Context, Params, InheritedParams> CliBindings<Context>
|
impl<Context, Params, InheritedParams> CliBindings<Context>
|
||||||
for ParentHandler<Context, Params, InheritedParams>
|
for ParentHandler<Context, Params, InheritedParams>
|
||||||
where
|
where
|
||||||
Context: IntoContext,
|
Context: crate::Context,
|
||||||
Params: FromArgMatches + CommandFactory + Serialize + Send + Sync + 'static,
|
Params: FromArgMatches + CommandFactory + Serialize + Send + Sync + 'static,
|
||||||
InheritedParams: Serialize + Send + Sync + 'static,
|
InheritedParams: Serialize + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
fn cli_command(&self, ctx_ty: TypeId) -> Command {
|
fn cli_command(&self) -> Command {
|
||||||
let mut base = Params::command().subcommand_required(true);
|
let mut base = Params::command().subcommand_required(true);
|
||||||
for (name, handlers) in &self.subcommands.0 {
|
for (name, handler) in &self.subcommands.0 {
|
||||||
match (
|
match (name, handler.cli()) {
|
||||||
name,
|
|
||||||
if let Some(handler) = handlers.get(&Some(ctx_ty)) {
|
|
||||||
handler.cli()
|
|
||||||
} else if let Some(handler) = handlers.get(&None) {
|
|
||||||
handler.cli()
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
) {
|
|
||||||
(Name(Some(name)), Some(cli)) => {
|
(Name(Some(name)), Some(cli)) => {
|
||||||
base = base.subcommand(cli.cli_command(ctx_ty).name(name));
|
base = base.subcommand(cli.cli_command().name(name));
|
||||||
}
|
}
|
||||||
(Name(None), Some(_)) => {
|
(Name(None), Some(_)) => {
|
||||||
base = base.subcommand_required(false);
|
base = base.subcommand_required(false);
|
||||||
@@ -298,7 +232,6 @@ where
|
|||||||
fn cli_parse(
|
fn cli_parse(
|
||||||
&self,
|
&self,
|
||||||
matches: &ArgMatches,
|
matches: &ArgMatches,
|
||||||
ctx_ty: TypeId,
|
|
||||||
) -> Result<(VecDeque<&'static str>, Value), clap::Error> {
|
) -> Result<(VecDeque<&'static str>, Value), clap::Error> {
|
||||||
let root_params = imbl_value::to_value(&Params::from_arg_matches(matches)?)
|
let root_params = imbl_value::to_value(&Params::from_arg_matches(matches)?)
|
||||||
.map_err(|e| clap::Error::raw(clap::error::ErrorKind::ValueValidation, e))?;
|
.map_err(|e| clap::Error::raw(clap::error::ErrorKind::ValueValidation, e))?;
|
||||||
@@ -308,10 +241,10 @@ where
|
|||||||
};
|
};
|
||||||
if let Some((Name(Some(name)), cli)) = self
|
if let Some((Name(Some(name)), cli)) = self
|
||||||
.subcommands
|
.subcommands
|
||||||
.get(ctx_ty, name)
|
.get(name)
|
||||||
.and_then(|(n, h)| h.cli().map(|c| (n, c)))
|
.and_then(|(n, h)| h.cli().map(|c| (n, c)))
|
||||||
{
|
{
|
||||||
let (mut method, params) = cli.cli_parse(matches, ctx_ty)?;
|
let (mut method, params) = cli.cli_parse(matches)?;
|
||||||
method.push_front(name);
|
method.push_front(name);
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
@@ -341,12 +274,12 @@ where
|
|||||||
}
|
}
|
||||||
if let Some((_, cli)) = self
|
if let Some((_, cli)) = self
|
||||||
.subcommands
|
.subcommands
|
||||||
.get(context.inner_type_id(), cmd)
|
.get(cmd)
|
||||||
.and_then(|(n, h)| h.cli().map(|c| (n, c)))
|
.and_then(|(n, h)| h.cli().map(|c| (n, c)))
|
||||||
{
|
{
|
||||||
cli.cli_display(
|
cli.cli_display(
|
||||||
HandleAnyArgs {
|
HandleAnyArgs {
|
||||||
context: context.upcast(),
|
context,
|
||||||
parent_method,
|
parent_method,
|
||||||
method,
|
method,
|
||||||
params: raw_params,
|
params: raw_params,
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
use std::any::TypeId;
|
|
||||||
|
|
||||||
use axum::body::Body;
|
use axum::body::Body;
|
||||||
use axum::extract::Request;
|
use axum::extract::Request;
|
||||||
use axum::handler::Handler;
|
use axum::handler::Handler;
|
||||||
@@ -257,7 +255,7 @@ impl<Context: crate::Context> HttpServer<Context> {
|
|||||||
match self
|
match self
|
||||||
.inner
|
.inner
|
||||||
.root_handler
|
.root_handler
|
||||||
.method_from_dots(req.method.as_str(), TypeId::of::<Context>())
|
.method_from_dots(req.method.as_str())
|
||||||
{
|
{
|
||||||
Some(a) => a,
|
Some(a) => a,
|
||||||
None => {
|
None => {
|
||||||
@@ -267,7 +265,6 @@ impl<Context: crate::Context> HttpServer<Context> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
TypeId::of::<Context>(),
|
|
||||||
)
|
)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(key, value)| (key.into(), value))
|
.map(|(key, value)| (key.into(), value))
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
use std::any::TypeId;
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
@@ -8,7 +7,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::{AnyHandler, HandleAny, HandleAnyArgs, IntoContext, ParentHandler};
|
use crate::{AnyHandler, Empty, HandleAny, HandleAnyArgs, ParentHandler};
|
||||||
|
|
||||||
pub type GenericRpcMethod = yajrc::GenericRpcMethod<String, Value, Value>;
|
pub type GenericRpcMethod = yajrc::GenericRpcMethod<String, Value, Value>;
|
||||||
pub type RpcRequest = yajrc::RpcRequest<GenericRpcMethod>;
|
pub type RpcRequest = yajrc::RpcRequest<GenericRpcMethod>;
|
||||||
@@ -23,7 +22,7 @@ pub use socket::*;
|
|||||||
|
|
||||||
pub struct Server<Context: crate::Context> {
|
pub struct Server<Context: crate::Context> {
|
||||||
make_ctx: Arc<dyn Fn() -> BoxFuture<'static, Result<Context, RpcError>> + Send + Sync>,
|
make_ctx: Arc<dyn Fn() -> BoxFuture<'static, Result<Context, RpcError>> + Send + Sync>,
|
||||||
root_handler: Arc<AnyHandler<Context, ParentHandler<Context>>>,
|
root_handler: Arc<AnyHandler<Context, Empty, ParentHandler<Context>>>,
|
||||||
}
|
}
|
||||||
impl<Context: crate::Context> Clone for Server<Context> {
|
impl<Context: crate::Context> Clone for Server<Context> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
@@ -55,14 +54,13 @@ impl<Context: crate::Context> Server<Context> {
|
|||||||
let (make_ctx, root_handler, method) = (
|
let (make_ctx, root_handler, method) = (
|
||||||
self.make_ctx.clone(),
|
self.make_ctx.clone(),
|
||||||
self.root_handler.clone(),
|
self.root_handler.clone(),
|
||||||
self.root_handler
|
self.root_handler.method_from_dots(method),
|
||||||
.method_from_dots(method, TypeId::of::<Context>()),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
async move {
|
async move {
|
||||||
root_handler
|
root_handler
|
||||||
.handle_async(HandleAnyArgs {
|
.handle_async(HandleAnyArgs {
|
||||||
context: make_ctx().await?.upcast(),
|
context: make_ctx().await?,
|
||||||
parent_method: VecDeque::new(),
|
parent_method: VecDeque::new(),
|
||||||
method: method.ok_or_else(|| yajrc::METHOD_NOT_FOUND_ERROR)?,
|
method: method.ok_or_else(|| yajrc::METHOD_NOT_FOUND_ERROR)?,
|
||||||
params,
|
params,
|
||||||
|
|||||||
@@ -7,8 +7,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, Empty,
|
call_remote_socket, from_fn, from_fn_async, CallRemote, CliApp, Context, Empty, HandlerExt,
|
||||||
HandlerExt, ParentHandler, Server,
|
ParentHandler, Server,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tokio::runtime::{Handle, Runtime};
|
use tokio::runtime::{Handle, Runtime};
|
||||||
@@ -102,7 +102,7 @@ fn make_server() -> Server<ServerContext> {
|
|||||||
Server::new(move || ready(Ok(ctx.clone())), make_api())
|
Server::new(move || ready(Ok(ctx.clone())), make_api())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_api() -> ParentHandler {
|
fn make_api<C: Context>() -> ParentHandler<C> {
|
||||||
async fn a_hello(_: CliContext) -> Result<String, RpcError> {
|
async fn a_hello(_: CliContext) -> Result<String, RpcError> {
|
||||||
Ok::<_, RpcError>("Async Subcommand".to_string())
|
Ok::<_, RpcError>("Async Subcommand".to_string())
|
||||||
}
|
}
|
||||||
@@ -118,8 +118,8 @@ fn make_api() -> ParentHandler {
|
|||||||
struct InheritParams {
|
struct InheritParams {
|
||||||
donde: String,
|
donde: String,
|
||||||
}
|
}
|
||||||
ParentHandler::new()
|
ParentHandler::<C>::new()
|
||||||
.subcommand(
|
.subcommand::<C, _>(
|
||||||
"echo",
|
"echo",
|
||||||
from_fn_async(
|
from_fn_async(
|
||||||
|c: ServerContext, EchoParams { next }: EchoParams| async move {
|
|c: ServerContext, EchoParams { next }: EchoParams| async move {
|
||||||
@@ -133,14 +133,14 @@ fn make_api() -> ParentHandler {
|
|||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
"hello",
|
"hello",
|
||||||
from_fn(|_: AnyContext, HelloParams { whom }: HelloParams| {
|
from_fn(|_: C, HelloParams { whom }: HelloParams| {
|
||||||
Ok::<_, RpcError>(format!("Hello {whom}").to_string())
|
Ok::<_, RpcError>(format!("Hello {whom}").to_string())
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.subcommand("a_hello", from_fn_async(a_hello))
|
.subcommand("a_hello", from_fn_async(a_hello))
|
||||||
.subcommand(
|
.subcommand(
|
||||||
"dondes",
|
"dondes",
|
||||||
ParentHandler::<AnyContext, InheritParams>::new().subcommand(
|
ParentHandler::<C, InheritParams>::new().subcommand(
|
||||||
"donde",
|
"donde",
|
||||||
from_fn(|c: CliContext, _: (), donde| {
|
from_fn(|c: CliContext, _: (), donde| {
|
||||||
Ok::<_, RpcError>(
|
Ok::<_, RpcError>(
|
||||||
@@ -157,7 +157,7 @@ fn make_api() -> ParentHandler {
|
|||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
"fizz",
|
"fizz",
|
||||||
ParentHandler::<AnyContext, InheritParams>::new().root_handler(
|
ParentHandler::<C, InheritParams>::new().root_handler(
|
||||||
from_fn(|c: CliContext, _: Empty, InheritParams { donde }| {
|
from_fn(|c: CliContext, _: Empty, InheritParams { donde }| {
|
||||||
Ok::<_, RpcError>(
|
Ok::<_, RpcError>(
|
||||||
format!(
|
format!(
|
||||||
@@ -172,7 +172,7 @@ fn make_api() -> ParentHandler {
|
|||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
"error",
|
"error",
|
||||||
ParentHandler::<AnyContext, InheritParams>::new().root_handler(
|
ParentHandler::<C, InheritParams>::new().root_handler(
|
||||||
from_fn(|_: CliContext, _: Empty, InheritParams { .. }| {
|
from_fn(|_: CliContext, _: Empty, InheritParams { .. }| {
|
||||||
Err::<String, _>(RpcError {
|
Err::<String, _>(RpcError {
|
||||||
code: 1,
|
code: 1,
|
||||||
|
|||||||
Reference in New Issue
Block a user