use std::any::TypeId; use std::collections::VecDeque; use std::fmt::Debug; use std::marker::PhantomData; use std::ops::Deref; use std::sync::Arc; use clap::{ArgMatches, Command, Parser}; use futures::Future; use imbl_value::imbl::OrdMap; use imbl_value::Value; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; use yajrc::RpcError; use crate::util::{internal_error, invalid_params, Flat}; pub mod adapters; pub mod from_fn; pub mod parent; pub use adapters::*; pub use from_fn::*; pub use parent::*; 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> where H: HandlerTypes, H::InheritedParams: OrEmpty, H::Params: DeserializeOwned, { let Self { context, parent_method, method, params, inherited, } = self; Ok(HandlerArgs { context, parent_method, method, params: imbl_value::from_value(params.clone())?, inherited_params: OrEmpty::from_t(inherited), raw_params: params, }) } } #[async_trait::async_trait] pub(crate) trait HandleAny: Send + Sync { type Inherited: Send; fn handle_sync( &self, handle_args: HandleAnyArgs, ) -> Result; async fn handle_async( &self, handle_args: HandleAnyArgs, ) -> Result; 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 { type Inherited = T::Inherited; fn handle_sync( &self, handle_args: HandleAnyArgs, ) -> Result { self.deref().handle_sync(handle_args) } async fn handle_async( &self, handle_args: HandleAnyArgs, ) -> Result { self.deref().handle_async(handle_args).await } fn metadata(&self, method: VecDeque<&'static str>) -> OrdMap<&'static str, Value> { self.deref().metadata(method) } fn method_from_dots(&self, method: &str) -> Option> { self.deref().method_from_dots(method) } fn cli(&self) -> Option<&dyn CliBindingsAny> { self.deref().cli() } } pub(crate) trait CliBindingsAny { type Inherited; fn cli_command(&self) -> Command; fn cli_parse( &self, matches: &ArgMatches, ) -> Result<(VecDeque<&'static str>, Value), clap::Error>; fn cli_display( &self, handle_args: HandleAnyArgs, result: Value, ) -> Result<(), RpcError>; } pub trait CliBindings: HandlerTypes { const NO_CLI: bool = false; fn cli_command(&self) -> Command; fn cli_parse( &self, matches: &ArgMatches, ) -> Result<(VecDeque<&'static str>, Value), clap::Error>; fn cli_display( &self, handle_args: HandlerArgsFor, result: Self::Ok, ) -> Result<(), Self::Err>; } pub trait PrintCliResult: HandlerTypes { fn print( &self, handle_args: HandlerArgsFor, result: Self::Ok, ) -> Result<(), Self::Err>; } #[allow(private_interfaces)] 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 { fn clone(&self) -> Self { Self(self.0.clone()) } } impl Debug for DynHandler { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("DynHandler").finish() } } #[async_trait::async_trait] impl HandleAny for DynHandler { type Inherited = Inherited; fn handle_sync( &self, handle_args: HandleAnyArgs, ) -> Result { self.0.handle_sync(handle_args) } async fn handle_async( &self, handle_args: HandleAnyArgs, ) -> Result { self.0.handle_async(handle_args).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) } fn cli(&self) -> Option<&dyn CliBindingsAny> { self.0.cli() } } #[allow(type_alias_bounds)] pub type HandlerArgsFor = HandlerArgs; #[derive(Debug, Clone)] pub struct HandlerArgs< Context: crate::Context, Params: Send + Sync = Empty, InheritedParams: Send + Sync = Empty, > { pub context: Context, pub parent_method: VecDeque<&'static str>, pub method: VecDeque<&'static str>, pub params: Params, pub inherited_params: InheritedParams, pub raw_params: Value, } pub trait HandlerTypes { type Params: Send + Sync; type InheritedParams: Send + Sync; type Ok: Send + Sync; type Err: Send + Sync; } pub trait HandlerFor: HandlerTypes + Clone + Send + Sync + 'static { fn handle_sync( &self, handle_args: HandlerArgsFor, ) -> Result { if let Some(rt) = handle_args.context.runtime() { rt.block_on(self.handle_async(handle_args)) } else { tokio::runtime::Handle::current().block_on(self.handle_async(handle_args)) } } fn handle_async( &self, handle_args: HandlerArgsFor, ) -> impl Future> + Send; fn handle_async_with_sync<'a>( &'a self, handle_args: HandlerArgsFor, ) -> impl Future> + Send + 'a { async move { self.handle_sync(handle_args) } } fn handle_async_with_sync_blocking<'a>( &'a self, handle_args: HandlerArgsFor, ) -> impl Future> + Send + 'a { async move { let s = self.clone(); if let Some(rt) = handle_args.context.runtime() { rt.spawn_blocking(move || s.handle_sync(handle_args)).await } else { tokio::runtime::Handle::current() .spawn_blocking(move || s.handle_sync(handle_args)) .await } .unwrap() } } #[allow(unused_variables)] fn metadata(&self, method: VecDeque<&'static str>) -> OrdMap<&'static str, Value> { OrdMap::new() } #[allow(unused_variables)] fn method_from_dots(&self, method: &str) -> Option> { if method.is_empty() { Some(VecDeque::new()) } else { None } } } pub trait Handler { type H: HandlerTypes; fn handler_for(self) -> Option>; } pub struct WithContext { _phantom: PhantomData, handler: H, } 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, handler, } } } 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) .finish() } } #[async_trait::async_trait] impl HandleAny for AnyHandler where Context: crate::Context, H: HandlerFor + CliBindings, H::Params: DeserializeOwned, H::Ok: Serialize + DeserializeOwned, H::InheritedParams: OrEmpty, RpcError: From, Inherited: Send + Sync, { type Inherited = Inherited; fn handle_sync( &self, handle_args: HandleAnyArgs, ) -> Result { imbl_value::to_value( &self .handler .handle_sync(handle_args.downcast::().map_err(invalid_params)?)?, ) .map_err(internal_error) } async fn handle_async( &self, handle_args: HandleAnyArgs, ) -> Result { imbl_value::to_value( &self .handler .handle_async(handle_args.downcast::().map_err(invalid_params)?) .await?, ) .map_err(internal_error) } fn metadata(&self, method: VecDeque<&'static str>) -> OrdMap<&'static str, Value> { self.handler.metadata(method) } fn method_from_dots(&self, method: &str) -> Option> { self.handler.method_from_dots(method) } fn cli(&self) -> Option<&dyn CliBindingsAny> { if H::NO_CLI { None } else { Some(self) } } } impl CliBindingsAny for AnyHandler where Context: crate::Context, H: CliBindings, H::Params: DeserializeOwned, H::Ok: Serialize + DeserializeOwned, RpcError: From, H::InheritedParams: OrEmpty, Inherited: Send + Sync, { type Inherited = Inherited; fn cli_command(&self) -> Command { self.handler.cli_command() } fn cli_parse( &self, matches: &ArgMatches, ) -> Result<(VecDeque<&'static str>, Value), clap::Error> { self.handler.cli_parse(matches) } fn cli_display( &self, handle_args: HandleAnyArgs, result: Value, ) -> Result<(), RpcError> { self.handler .cli_display( handle_args.downcast::().map_err(invalid_params)?, imbl_value::from_value(result).map_err(internal_error)?, ) .map_err(RpcError::from) } } #[derive(Debug, Clone, Copy, Deserialize, Serialize, Parser)] pub struct Empty {} pub trait OrEmpty { fn from_t(t: T) -> Self; } impl OrEmpty for T { fn from_t(t: T) -> Self { t } } impl OrEmpty> for Empty { fn from_t(_: Flat) -> Self { Empty {} } } #[derive(Debug, Clone, Copy, Deserialize, Serialize, Parser)] pub enum Never {}