mirror of
https://github.com/Start9Labs/rpc-toolkit.git
synced 2026-03-25 18:10:55 +00:00
better ts adapters
This commit is contained in:
@@ -44,6 +44,9 @@ pub trait HandlerExt<Context: crate::Context>: HandlerFor<Context> + Sized {
|
||||
fn with_about<M>(self, message: M) -> WithAbout<M, Self>
|
||||
where
|
||||
M: IntoResettable<StyledStr>;
|
||||
fn no_ts(self) -> NoTS<Self>;
|
||||
fn unknown_ts(self) -> UnknownTS<Self>;
|
||||
fn custom_ts(self, params_ty: String, return_ty: String) -> CustomTS<Self>;
|
||||
}
|
||||
|
||||
impl<Context: crate::Context, T: HandlerFor<Context> + Sized> HandlerExt<Context> for T {
|
||||
@@ -107,6 +110,22 @@ impl<Context: crate::Context, T: HandlerFor<Context> + Sized> HandlerExt<Context
|
||||
message,
|
||||
}
|
||||
}
|
||||
|
||||
fn no_ts(self) -> NoTS<Self> {
|
||||
NoTS(self)
|
||||
}
|
||||
|
||||
fn unknown_ts(self) -> UnknownTS<Self> {
|
||||
UnknownTS(self)
|
||||
}
|
||||
|
||||
fn custom_ts(self, params_ty: String, return_ty: String) -> CustomTS<Self> {
|
||||
CustomTS {
|
||||
handler: self,
|
||||
params_ty,
|
||||
return_ty,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -648,7 +667,7 @@ impl<Context, H, Inherited, RemoteContext> Handler<Inherited>
|
||||
where
|
||||
Context: crate::Context + CallRemote<RemoteContext>,
|
||||
RemoteContext: crate::Context,
|
||||
H: HandlerFor<RemoteContext> + CliBindings<Context>,
|
||||
H: HandlerFor<RemoteContext> + CliBindings<Context> + crate::handler::HandlerTS,
|
||||
H::Ok: Serialize + DeserializeOwned,
|
||||
H::Err: From<RpcError>,
|
||||
H::Params: Serialize + DeserializeOwned,
|
||||
@@ -926,3 +945,304 @@ where
|
||||
self.handler.cli_display(handler, result)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct NoTS<H>(pub H);
|
||||
|
||||
impl<H> HandlerTypes for NoTS<H>
|
||||
where
|
||||
H: HandlerTypes,
|
||||
{
|
||||
type Params = H::Params;
|
||||
type InheritedParams = H::InheritedParams;
|
||||
type Ok = H::Ok;
|
||||
type Err = H::Err;
|
||||
}
|
||||
|
||||
#[cfg(feature = "ts-rs")]
|
||||
impl<H> crate::handler::HandlerTS for NoTS<H> {
|
||||
fn type_info(&self) -> Option<String> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl<Context, H> HandlerFor<Context> for NoTS<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> CliBindings<Context> for NoTS<H>
|
||||
where
|
||||
Context: crate::Context,
|
||||
H: CliBindings<Context>,
|
||||
{
|
||||
fn cli_command(&self) -> clap::Command {
|
||||
self.0.cli_command()
|
||||
}
|
||||
fn cli_parse(
|
||||
&self,
|
||||
arg_matches: &clap::ArgMatches,
|
||||
) -> Result<(VecDeque<&'static str>, Value), clap::Error> {
|
||||
self.0.cli_parse(arg_matches)
|
||||
}
|
||||
fn cli_display(
|
||||
&self,
|
||||
handler: HandlerArgsFor<Context, Self>,
|
||||
result: Self::Ok,
|
||||
) -> Result<(), Self::Err> {
|
||||
self.0.cli_display(handler, result)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct UnknownTS<H>(pub H);
|
||||
|
||||
impl<H> HandlerTypes for UnknownTS<H>
|
||||
where
|
||||
H: HandlerTypes,
|
||||
{
|
||||
type Params = H::Params;
|
||||
type InheritedParams = H::InheritedParams;
|
||||
type Ok = H::Ok;
|
||||
type Err = H::Err;
|
||||
}
|
||||
|
||||
#[cfg(feature = "ts-rs")]
|
||||
impl<H> crate::handler::HandlerTS for UnknownTS<H> {
|
||||
fn type_info(&self) -> Option<String> {
|
||||
Some("{_PARAMS:unknown,_RETURN:unknown}".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl<Context, H> HandlerFor<Context> for UnknownTS<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> CliBindings<Context> for UnknownTS<H>
|
||||
where
|
||||
Context: crate::Context,
|
||||
H: CliBindings<Context>,
|
||||
{
|
||||
fn cli_command(&self) -> clap::Command {
|
||||
self.0.cli_command()
|
||||
}
|
||||
fn cli_parse(
|
||||
&self,
|
||||
arg_matches: &clap::ArgMatches,
|
||||
) -> Result<(VecDeque<&'static str>, Value), clap::Error> {
|
||||
self.0.cli_parse(arg_matches)
|
||||
}
|
||||
fn cli_display(
|
||||
&self,
|
||||
handler: HandlerArgsFor<Context, Self>,
|
||||
result: Self::Ok,
|
||||
) -> Result<(), Self::Err> {
|
||||
self.0.cli_display(handler, result)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CustomTS<H> {
|
||||
pub handler: H,
|
||||
pub params_ty: String,
|
||||
pub return_ty: String,
|
||||
}
|
||||
|
||||
impl<H> HandlerTypes for CustomTS<H>
|
||||
where
|
||||
H: HandlerTypes,
|
||||
{
|
||||
type Params = H::Params;
|
||||
type InheritedParams = H::InheritedParams;
|
||||
type Ok = H::Ok;
|
||||
type Err = H::Err;
|
||||
}
|
||||
|
||||
#[cfg(feature = "ts-rs")]
|
||||
impl<H> crate::handler::HandlerTS for CustomTS<H> {
|
||||
fn type_info(&self) -> Option<String> {
|
||||
Some(format!(
|
||||
"{{_PARAMS:{},_RETURN:{}}}",
|
||||
self.params_ty, self.return_ty
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl<Context, H> HandlerFor<Context> for CustomTS<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.handler.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.handler
|
||||
.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.handler.metadata(method)
|
||||
}
|
||||
fn method_from_dots(&self, method: &str) -> Option<VecDeque<&'static str>> {
|
||||
self.handler.method_from_dots(method)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Context, H> CliBindings<Context> for CustomTS<H>
|
||||
where
|
||||
Context: crate::Context,
|
||||
H: CliBindings<Context>,
|
||||
{
|
||||
fn cli_command(&self) -> clap::Command {
|
||||
self.handler.cli_command()
|
||||
}
|
||||
fn cli_parse(
|
||||
&self,
|
||||
arg_matches: &clap::ArgMatches,
|
||||
) -> Result<(VecDeque<&'static str>, Value), clap::Error> {
|
||||
self.handler.cli_parse(arg_matches)
|
||||
}
|
||||
fn cli_display(
|
||||
&self,
|
||||
handler: HandlerArgsFor<Context, Self>,
|
||||
result: Self::Ok,
|
||||
) -> Result<(), Self::Err> {
|
||||
self.handler.cli_display(handler, result)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,28 +55,22 @@ impl<Context: crate::Context, Inherited: Send + Sync> HandleAnyArgs<Context, Inh
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "ts-rs")]
|
||||
pub(crate) trait HandleAnyTS {
|
||||
fn type_info(&self) -> Option<String>;
|
||||
#[allow(dead_code)]
|
||||
fn type_info(&self) -> Option<String> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "ts-rs")]
|
||||
impl<T: HandleAnyTS> HandleAnyTS for Arc<T> {
|
||||
fn type_info(&self) -> Option<String> {
|
||||
self.deref().type_info()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "ts-rs")]
|
||||
pub(crate) trait HandleAnyRequires: HandleAnyTS + Send + Sync {}
|
||||
#[cfg(feature = "ts-rs")]
|
||||
impl<T: HandleAnyTS + Send + Sync> HandleAnyRequires for T {}
|
||||
|
||||
#[cfg(not(feature = "ts-rs"))]
|
||||
pub(crate) trait HandleAnyRequires: Send + Sync {}
|
||||
#[cfg(not(feature = "ts-rs"))]
|
||||
impl<T: Send + Sync> HandleAnyRequires for T {}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
pub(crate) trait HandleAny<Context>: HandleAnyRequires {
|
||||
type Inherited: Send;
|
||||
@@ -175,7 +169,6 @@ impl<Context, Inherited> Debug for DynHandler<Context, Inherited> {
|
||||
f.debug_struct("DynHandler").finish()
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "ts-rs")]
|
||||
impl<Context, Inherited> HandleAnyTS for DynHandler<Context, Inherited> {
|
||||
fn type_info(&self) -> Option<String> {
|
||||
self.0.type_info()
|
||||
@@ -234,19 +227,18 @@ pub trait HandlerTypes {
|
||||
type Err: Send + Sync;
|
||||
}
|
||||
|
||||
#[cfg(feature = "ts-rs")]
|
||||
pub trait HandlerTS {
|
||||
fn type_info(&self) -> Option<String>;
|
||||
}
|
||||
|
||||
#[cfg(feature = "ts-rs")]
|
||||
pub trait HandlerRequires: HandlerTS + HandlerTypes + Clone + Send + Sync + 'static {}
|
||||
#[cfg(feature = "ts-rs")]
|
||||
impl<T: HandlerTS + HandlerTypes + Clone + Send + Sync + 'static> HandlerRequires for T {}
|
||||
#[cfg(not(feature = "ts-rs"))]
|
||||
impl<T: HandlerTypes> HandlerTS for T {
|
||||
fn type_info(&self) -> Option<String> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "ts-rs"))]
|
||||
pub trait HandlerRequires: HandlerTypes + Clone + Send + Sync + 'static {}
|
||||
#[cfg(not(feature = "ts-rs"))]
|
||||
impl<T: HandlerTypes + Clone + Send + Sync + 'static> HandlerRequires for T {}
|
||||
|
||||
pub trait HandlerFor<Context: crate::Context>: HandlerRequires {
|
||||
@@ -321,7 +313,7 @@ impl<Context, H> WithContext<Context, H> {
|
||||
impl<Context, Inherited, H> Handler<Inherited> for WithContext<Context, H>
|
||||
where
|
||||
Context: crate::Context,
|
||||
H: HandlerFor<Context> + CliBindings<Context>,
|
||||
H: HandlerFor<Context> + CliBindings<Context> + HandlerTS,
|
||||
H::Ok: Serialize + DeserializeOwned,
|
||||
H::Params: DeserializeOwned,
|
||||
H::InheritedParams: OrEmpty<Inherited>,
|
||||
@@ -362,10 +354,9 @@ impl<Context, Inherited, H: std::fmt::Debug> std::fmt::Debug for AnyHandler<Cont
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "ts-rs")]
|
||||
impl<Context, Inherited, H> HandleAnyTS for AnyHandler<Context, Inherited, H>
|
||||
where
|
||||
H: crate::handler::HandlerTS,
|
||||
H: HandlerTS,
|
||||
{
|
||||
fn type_info(&self) -> Option<String> {
|
||||
self.handler.type_info()
|
||||
@@ -376,7 +367,7 @@ where
|
||||
impl<Context, Inherited, H> HandleAny<Context> for AnyHandler<Context, Inherited, H>
|
||||
where
|
||||
Context: crate::Context,
|
||||
H: HandlerFor<Context> + CliBindings<Context>,
|
||||
H: HandlerFor<Context> + CliBindings<Context> + HandlerTS,
|
||||
H::Params: DeserializeOwned,
|
||||
H::Ok: Serialize + DeserializeOwned,
|
||||
H::InheritedParams: OrEmpty<Inherited>,
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#![cfg_attr(feature = "nightly", feature(const_trait_impl, const_type_id))]
|
||||
|
||||
pub use cli::*;
|
||||
// pub use command::*;
|
||||
pub use context::*;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
use clap::Parser;
|
||||
use rpc_toolkit::{from_fn_async, Context, Empty, HandlerTS, ParentHandler, Server};
|
||||
use rpc_toolkit::{
|
||||
from_fn, from_fn_async, Context, Empty, HandlerExt, HandlerTS, ParentHandler, Server,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use yajrc::RpcError;
|
||||
|
||||
@@ -14,10 +16,19 @@ struct Thing1Params {
|
||||
thing: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Parser)]
|
||||
struct NoTSParams {
|
||||
foo: String,
|
||||
}
|
||||
|
||||
async fn thing1_handler(_ctx: TestContext, params: Thing1Params) -> Result<String, RpcError> {
|
||||
Ok(format!("Thing1 is {}", params.thing))
|
||||
}
|
||||
|
||||
fn no_ts_handler(_ctx: TestContext, params: NoTSParams) -> Result<String, RpcError> {
|
||||
Ok(format!("foo:{}", params.foo))
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Parser)]
|
||||
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
|
||||
struct GroupParams {
|
||||
@@ -38,7 +49,8 @@ async fn test_basic_server() {
|
||||
from_fn_async(|_ctx: TestContext, params: GroupParams| async move {
|
||||
Ok::<_, RpcError>(format!("verbose: {}", params.verbose))
|
||||
}),
|
||||
),
|
||||
)
|
||||
.subcommand("no-ts", from_fn(no_ts_handler).no_ts()),
|
||||
);
|
||||
|
||||
println!("{}", root_handler.type_info().unwrap_or_default());
|
||||
|
||||
Reference in New Issue
Block a user