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