mirror of
https://github.com/Start9Labs/rpc-toolkit.git
synced 2026-03-26 02:11:56 +00:00
wip: replace ts lib
This commit is contained in:
65
Cargo.lock
generated
65
Cargo.lock
generated
@@ -1198,8 +1198,8 @@ dependencies = [
|
||||
"thiserror 2.0.17",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"ts-rs",
|
||||
"url",
|
||||
"visit-rs",
|
||||
"yajrc",
|
||||
]
|
||||
|
||||
@@ -1495,15 +1495,6 @@ dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.69"
|
||||
@@ -1704,28 +1695,6 @@ version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
|
||||
|
||||
[[package]]
|
||||
name = "ts-rs"
|
||||
version = "9.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b44017f9f875786e543595076374b9ef7d13465a518dd93d6ccdbf5b432dde8c"
|
||||
dependencies = [
|
||||
"thiserror 1.0.69",
|
||||
"ts-rs-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ts-rs-macros"
|
||||
version = "9.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c88cc88fd23b5a04528f3a8436024f20010a16ec18eb23c164b1242f65860130"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.22"
|
||||
@@ -1774,6 +1743,29 @@ version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "visit-rs"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ea0fdb05dd98029f7e226ccd11bd7184ad68566365547930bdde9ae79b5ce3d"
|
||||
dependencies = [
|
||||
"async-stream",
|
||||
"futures",
|
||||
"serde",
|
||||
"visit-rs-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "visit-rs-derive"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8dde3216fefaf10421d9509f88bc5a480b5fb3fe48779ca4f148e75896d3f5ad"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "want"
|
||||
version = "0.3.1"
|
||||
@@ -1866,15 +1858,6 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
|
||||
dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.1.3"
|
||||
|
||||
19
Cargo.toml
19
Cargo.toml
@@ -1,31 +1,32 @@
|
||||
[package]
|
||||
authors = ["Aiden McClelland <me@drbonez.dev>"]
|
||||
edition = "2018"
|
||||
name = "rpc-toolkit"
|
||||
version = "0.3.2"
|
||||
description = "A toolkit for creating JSON-RPC 2.0 servers with automatic cli bindings"
|
||||
license = "MIT"
|
||||
documentation = "https://docs.rs/rpc-toolkit"
|
||||
keywords = ["json", "rpc", "cli"]
|
||||
edition = "2018"
|
||||
keywords = ["cli", "json", "rpc"]
|
||||
license = "MIT"
|
||||
name = "rpc-toolkit"
|
||||
repository = "https://github.com/Start9Labs/rpc-toolkit"
|
||||
version = "0.3.2"
|
||||
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
[features]
|
||||
cbor = ["serde_cbor"]
|
||||
default = ["cbor", "ts-rs"]
|
||||
default = ["cbor", "ts"]
|
||||
ts = ["visit-rs"]
|
||||
|
||||
[dependencies]
|
||||
axum = "0.8"
|
||||
async-stream = "0.3"
|
||||
async-trait = "0.1"
|
||||
axum = "0.8"
|
||||
clap = { version = "4", features = ["derive"] }
|
||||
futures = "0.3"
|
||||
http = "1"
|
||||
http-body-util = "0.1"
|
||||
# hyper = { version = "1", features = ["server", "http1", "http2", "client"] }
|
||||
itertools = "0.14"
|
||||
imbl-value = "0.4.3"
|
||||
itertools = "0.14"
|
||||
lazy_format = "2"
|
||||
lazy_static = "1.4"
|
||||
openssl = { version = "0.10", features = ["vendored"] }
|
||||
@@ -37,6 +38,6 @@ serde_json = "1.0"
|
||||
thiserror = "2.0"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
tokio-stream = { version = "0.1", features = ["io-util", "net"] }
|
||||
ts-rs = { version = "9.0.1", optional = true }
|
||||
url = "2"
|
||||
visit-rs = { version = "0.1.5", optional = true }
|
||||
yajrc = "0.1"
|
||||
|
||||
@@ -209,7 +209,7 @@ where
|
||||
type Err = RemoteHandler::Err;
|
||||
}
|
||||
|
||||
#[cfg(feature = "ts-rs")]
|
||||
#[cfg(feature = "ts")]
|
||||
impl<Context, RemoteContext, RemoteHandler, Extra> crate::handler::HandlerTS
|
||||
for CallRemoteHandler<Context, RemoteContext, RemoteHandler, Extra>
|
||||
where
|
||||
|
||||
@@ -139,7 +139,7 @@ impl<H: HandlerTypes> HandlerTypes for NoCli<H> {
|
||||
type Ok = H::Ok;
|
||||
type Err = H::Err;
|
||||
}
|
||||
#[cfg(feature = "ts-rs")]
|
||||
#[cfg(feature = "ts")]
|
||||
impl<H> crate::handler::HandlerTS for NoCli<H>
|
||||
where
|
||||
H: crate::handler::HandlerTS,
|
||||
@@ -233,7 +233,7 @@ impl<H: HandlerTypes> HandlerTypes for NoDisplay<H> {
|
||||
type Ok = H::Ok;
|
||||
type Err = H::Err;
|
||||
}
|
||||
#[cfg(feature = "ts-rs")]
|
||||
#[cfg(feature = "ts")]
|
||||
impl<H> crate::handler::HandlerTS for NoDisplay<H>
|
||||
where
|
||||
H: crate::handler::HandlerTS,
|
||||
@@ -355,7 +355,7 @@ where
|
||||
type Ok = H::Ok;
|
||||
type Err = H::Err;
|
||||
}
|
||||
#[cfg(feature = "ts-rs")]
|
||||
#[cfg(feature = "ts")]
|
||||
impl<P, H> crate::handler::HandlerTS for CustomDisplay<P, H>
|
||||
where
|
||||
H: crate::handler::HandlerTS,
|
||||
@@ -526,7 +526,7 @@ where
|
||||
type Ok = H::Ok;
|
||||
type Err = H::Err;
|
||||
}
|
||||
#[cfg(feature = "ts-rs")]
|
||||
#[cfg(feature = "ts")]
|
||||
impl<F, H, Context> crate::handler::HandlerTS for CustomDisplayFn<F, H, Context>
|
||||
where
|
||||
H: crate::handler::HandlerTS,
|
||||
@@ -751,7 +751,7 @@ where
|
||||
type Err = H::Err;
|
||||
}
|
||||
|
||||
#[cfg(feature = "ts-rs")]
|
||||
#[cfg(feature = "ts")]
|
||||
impl<Params, InheritedParams, H, F> crate::handler::HandlerTS
|
||||
for InheritanceHandler<Params, InheritedParams, H, F>
|
||||
where
|
||||
@@ -884,7 +884,7 @@ where
|
||||
type Ok = H::Ok;
|
||||
type Err = H::Err;
|
||||
}
|
||||
#[cfg(feature = "ts-rs")]
|
||||
#[cfg(feature = "ts")]
|
||||
impl<M, H> crate::handler::HandlerTS for WithAbout<M, H>
|
||||
where
|
||||
H: crate::handler::HandlerTS,
|
||||
@@ -988,7 +988,7 @@ where
|
||||
type Err = H::Err;
|
||||
}
|
||||
|
||||
#[cfg(feature = "ts-rs")]
|
||||
#[cfg(feature = "ts")]
|
||||
impl<H> crate::handler::HandlerTS for NoTS<H> {
|
||||
fn type_info(&self) -> Option<String> {
|
||||
None
|
||||
@@ -1088,7 +1088,7 @@ where
|
||||
type Err = H::Err;
|
||||
}
|
||||
|
||||
#[cfg(feature = "ts-rs")]
|
||||
#[cfg(feature = "ts")]
|
||||
impl<H: LeafHandler> crate::handler::HandlerTS for UnknownTS<H> {
|
||||
fn type_info(&self) -> Option<String> {
|
||||
Some("{_PARAMS:unknown,_RETURN:unknown}".to_string())
|
||||
@@ -1192,7 +1192,7 @@ where
|
||||
type Err = H::Err;
|
||||
}
|
||||
|
||||
#[cfg(feature = "ts-rs")]
|
||||
#[cfg(feature = "ts")]
|
||||
impl<H: LeafHandler> crate::handler::HandlerTS for CustomTS<H> {
|
||||
fn type_info(&self) -> Option<String> {
|
||||
Some(format!(
|
||||
|
||||
@@ -7,9 +7,9 @@ use imbl_value::imbl::OrdMap;
|
||||
use imbl_value::Value;
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::Serialize;
|
||||
#[cfg(feature = "ts-rs")]
|
||||
use ts_rs::TS;
|
||||
|
||||
#[cfg(feature = "ts")]
|
||||
use crate::ts::TSVisitor;
|
||||
use crate::util::PhantomData;
|
||||
use crate::{
|
||||
CliBindings, Empty, HandlerArgs, HandlerArgsFor, HandlerFor, HandlerTypes, LeafHandler,
|
||||
@@ -48,14 +48,15 @@ impl<F, T, E, Args> std::fmt::Debug for FromFn<F, T, E, Args> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "ts-rs")]
|
||||
#[cfg(feature = "ts")]
|
||||
impl<F, T, E, Args> crate::handler::HandlerTS for FromFn<F, T, E, Args>
|
||||
where
|
||||
Self: HandlerTypes,
|
||||
<Self as HandlerTypes>::Params: ts_rs::TS,
|
||||
<Self as HandlerTypes>::Ok: ts_rs::TS,
|
||||
visit_rs::Static<<Self as HandlerTypes>::Params>: visit_rs::Visit<TSVisitor>,
|
||||
visit_rs::Static<<Self as HandlerTypes>::Ok>: visit_rs::Visit<TSVisitor>,
|
||||
{
|
||||
fn type_info(&self) -> Option<String> {
|
||||
let mut visitor = TSVisitor::default();
|
||||
Some(format!(
|
||||
"{{_PARAMS:{},_RETURN:{}}}",
|
||||
<Self as HandlerTypes>::Params::inline_flattened(),
|
||||
@@ -173,7 +174,7 @@ impl<F, Fut, T, E, Args> std::fmt::Debug for FromFnAsync<F, Fut, T, E, Args> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "ts-rs")]
|
||||
#[cfg(feature = "ts")]
|
||||
impl<F, Fut, T, E, Args> crate::handler::HandlerTS for FromFnAsync<F, Fut, T, E, Args>
|
||||
where
|
||||
Self: HandlerTypes,
|
||||
@@ -285,7 +286,7 @@ impl<F, Fut, T, E, Args> std::fmt::Debug for FromFnAsyncLocal<F, Fut, T, E, Args
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "ts-rs")]
|
||||
#[cfg(feature = "ts")]
|
||||
impl<F, Fut, T, E, Args> crate::handler::HandlerTS for FromFnAsyncLocal<F, Fut, T, E, Args>
|
||||
where
|
||||
Self: HandlerTypes,
|
||||
|
||||
@@ -233,7 +233,7 @@ pub trait HandlerTS {
|
||||
fn type_info(&self) -> Option<String>;
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "ts-rs"))]
|
||||
#[cfg(not(feature = "ts"))]
|
||||
impl<T: HandlerTypes> HandlerTS for T {
|
||||
fn type_info(&self) -> Option<String> {
|
||||
None
|
||||
@@ -450,8 +450,8 @@ where
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Deserialize, Serialize, Parser)]
|
||||
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
|
||||
#[cfg_attr(feature = "ts-rs", ts(type = "{}"))]
|
||||
#[cfg_attr(feature = "ts", derive(ts_rs::TS))]
|
||||
#[cfg_attr(feature = "ts", ts(type = "{}"))]
|
||||
pub struct Empty {}
|
||||
|
||||
pub trait OrEmpty<T> {
|
||||
|
||||
@@ -7,14 +7,14 @@ use imbl_value::Value;
|
||||
use serde::Serialize;
|
||||
use yajrc::RpcError;
|
||||
|
||||
#[cfg(feature = "ts-rs")]
|
||||
#[cfg(feature = "ts")]
|
||||
use crate::handler::HandleAnyTS;
|
||||
use crate::util::{combine, Flat, PhantomData};
|
||||
use crate::{
|
||||
CliBindings, DynHandler, Empty, HandleAny, HandleAnyArgs, Handler, HandlerArgs, HandlerArgsFor,
|
||||
HandlerFor, HandlerRequires, HandlerTypes, WithContext,
|
||||
};
|
||||
#[cfg(feature = "ts-rs")]
|
||||
#[cfg(feature = "ts")]
|
||||
use crate::{CustomTS, UnknownTS};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
@@ -88,7 +88,7 @@ impl<Context, Params, InheritedParams> ParentHandler<Context, Params, InheritedP
|
||||
self.metadata.insert(key, value);
|
||||
self
|
||||
}
|
||||
#[cfg(feature = "ts-rs")]
|
||||
#[cfg(feature = "ts")]
|
||||
fn type_info_impl(&self, params_ty: &str) -> Option<String> {
|
||||
use std::fmt::Write;
|
||||
let mut res = "{".to_owned();
|
||||
@@ -169,7 +169,7 @@ where
|
||||
type Err = RpcError;
|
||||
}
|
||||
|
||||
#[cfg(feature = "ts-rs")]
|
||||
#[cfg(feature = "ts")]
|
||||
impl<Context, Params, InheritedParams> crate::handler::HandlerTS
|
||||
for ParentHandler<Context, Params, InheritedParams>
|
||||
where
|
||||
@@ -180,7 +180,7 @@ where
|
||||
self.type_info_impl(&Params::inline_flattened())
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "ts-rs")]
|
||||
#[cfg(feature = "ts")]
|
||||
impl<Context, Params, InheritedParams> crate::handler::HandlerTS
|
||||
for CustomTS<ParentHandler<Context, Params, InheritedParams>>
|
||||
where
|
||||
@@ -191,7 +191,7 @@ where
|
||||
self.handler.type_info_impl(&self.params_ty)
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "ts-rs")]
|
||||
#[cfg(feature = "ts")]
|
||||
impl<Context, Params, InheritedParams> crate::handler::HandlerTS
|
||||
for UnknownTS<ParentHandler<Context, Params, InheritedParams>>
|
||||
where
|
||||
|
||||
@@ -10,9 +10,8 @@ pub mod command_helpers;
|
||||
mod context;
|
||||
mod handler;
|
||||
mod server;
|
||||
#[cfg(feature = "ts")]
|
||||
pub mod ts;
|
||||
pub mod util;
|
||||
|
||||
#[cfg(feature = "ts-rs")]
|
||||
pub fn type_helpers() -> &'static str {
|
||||
include_str!("./type-helpers.ts")
|
||||
}
|
||||
#[cfg(feature = "ts")]
|
||||
77
src/ts.rs
Normal file
77
src/ts.rs
Normal file
@@ -0,0 +1,77 @@
|
||||
use visit_rs::{NamedStatic, Static, Visit, VisitFieldsStaticNamed, Visitor};
|
||||
|
||||
pub fn type_helpers() -> &'static str {
|
||||
include_str!("./type-helpers.ts")
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct TSVisitor {
|
||||
pub ts: String,
|
||||
}
|
||||
impl Visitor for TSVisitor {
|
||||
type Result = ();
|
||||
}
|
||||
|
||||
impl<T> Visit<TSVisitor> for Static<T>
|
||||
where
|
||||
T: VisitFieldsStaticNamed<TSVisitor>,
|
||||
{
|
||||
fn visit(&self, visitor: &mut TSVisitor) -> <TSVisitor as Visitor>::Result {
|
||||
if Self::IS_NAMED {
|
||||
visitor.ts.push_str("{");
|
||||
} else {
|
||||
visitor.ts.push_str("[");
|
||||
}
|
||||
self.visit_fields_static_named(visitor).collect::<()>();
|
||||
if Self::IS_NAMED {
|
||||
visitor.ts.push_str("}");
|
||||
} else {
|
||||
visitor.ts.push_str("]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Visit<TSVisitor> for NamedStatic<T>
|
||||
where
|
||||
Static<T>: Visit<TSVisitor>,
|
||||
{
|
||||
fn visit(&self, visitor: &mut TSVisitor) -> <TSVisitor as Visitor>::Result {
|
||||
if let Some(name) = self.name {
|
||||
if name.chars().all(|c| c.is_alphanumeric() || c == '_')
|
||||
&& name.chars().next().map_or(false, |c| c.is_alphabetic())
|
||||
{
|
||||
visitor.ts.push_str(name);
|
||||
} else {
|
||||
write!(
|
||||
&mut visitor.ts,
|
||||
"[{}]",
|
||||
serde_json::to_string(&name).unwrap()
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
visitor.ts.push_str(":");
|
||||
}
|
||||
Static::<T>::new().visit(visitor);
|
||||
if self.name.is_some() {
|
||||
visitor.ts.push(";");
|
||||
} else {
|
||||
visitor.ts.push(",");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_ts {
|
||||
($($ty:ty),+ => $ts:expr) => {
|
||||
$(
|
||||
impl Visit<TSVisitor> for Static<$ty> {
|
||||
fn visit(&self, visitor: &mut TSVisitor) -> <TSVisitor as Visitor>::Result {
|
||||
visitor.ts.push_str($ts);
|
||||
}
|
||||
}
|
||||
)+
|
||||
};
|
||||
}
|
||||
|
||||
impl_ts!(String => "string");
|
||||
impl_ts!(usize,u8,u16,u32,isize,i8,i16,i32,f32,f64 => "number");
|
||||
impl_ts!(u64,u128,i64,i128 => "bigint");
|
||||
@@ -11,7 +11,7 @@ struct TestContext;
|
||||
impl Context for TestContext {}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Parser)]
|
||||
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
|
||||
#[cfg_attr(feature = "ts", derive(ts_rs::TS))]
|
||||
struct Thing1Params {
|
||||
thing: String,
|
||||
}
|
||||
@@ -30,7 +30,7 @@ fn no_ts_handler(_ctx: TestContext, params: NoTSParams) -> Result<String, RpcErr
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Parser)]
|
||||
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
|
||||
#[cfg_attr(feature = "ts", derive(ts_rs::TS))]
|
||||
struct GroupParams {
|
||||
#[arg(short, long)]
|
||||
verbose: bool,
|
||||
|
||||
Reference in New Issue
Block a user