Compare commits

...

2 commits

Author SHA1 Message Date
TotallyNot 73358b70cc
chore: updated schemas 2025-05-19 20:09:38 +02:00
TotallyNot b4ce0c764e
feat: allow arbitrary deserialisation from unions 2025-05-01 16:10:24 +02:00
12 changed files with 1676 additions and 141 deletions

84
Cargo.lock generated
View file

@ -55,9 +55,9 @@ dependencies = [
[[package]]
name = "async-compression"
version = "0.4.22"
version = "0.4.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59a194f9d963d8099596278594b3107448656ba73831c9d8c783e613ce86da64"
checksum = "b37fc50485c4f3f736a4fb14199f6d5f5ba008d7f28fe710306c92780f004c07"
dependencies = [
"brotli",
"futures-core",
@ -159,9 +159,9 @@ dependencies = [
[[package]]
name = "brotli"
version = "7.0.0"
version = "8.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc97b8f16f944bba54f0433f07e30be199b6dc2bd25937444bbad560bcea29bd"
checksum = "cf19e729cdbd51af9a397fb9ef8ac8378007b797f8273cfbfdf45dcaa316167b"
dependencies = [
"alloc-no-stdlib",
"alloc-stdlib",
@ -170,9 +170,9 @@ dependencies = [
[[package]]
name = "brotli-decompressor"
version = "4.0.3"
version = "5.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a334ef7c9e23abf0ce748e8cd309037da93e606ad52eb372e4ce327a0dcfbdfd"
checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03"
dependencies = [
"alloc-no-stdlib",
"alloc-stdlib",
@ -198,9 +198,9 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
[[package]]
name = "cc"
version = "1.2.19"
version = "1.2.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e3a13707ac958681c13b39b458c073d0d9bc8a22cb1b2f4c8e55eb72c13f362"
checksum = "04da6a0d40b948dfc4fa8f5bbf402b0fc1a64a28dbf7d12ffd683550f2c1b63a"
dependencies = [
"shlex",
]
@ -219,9 +219,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
[[package]]
name = "chrono"
version = "0.4.40"
version = "0.4.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c"
checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d"
dependencies = [
"android-tzdata",
"iana-time-zone",
@ -607,9 +607,9 @@ dependencies = [
[[package]]
name = "getrandom"
version = "0.2.15"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
dependencies = [
"cfg-if",
"js-sys",
@ -659,9 +659,9 @@ dependencies = [
[[package]]
name = "hashbrown"
version = "0.15.2"
version = "0.15.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3"
dependencies = [
"allocator-api2",
"equivalent",
@ -1252,9 +1252,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
[[package]]
name = "openssl-sys"
version = "0.9.107"
version = "0.9.108"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8288979acd84749c744a9014b4382d42b8f7b2592847b5afb2ed29e5d16ede07"
checksum = "e145e1651e858e820e4860f7b9c5e169bc1d8ce1c86043be79fa7b7634821847"
dependencies = [
"cc",
"libc",
@ -1366,9 +1366,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.94"
version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
dependencies = [
"unicode-ident",
]
@ -1395,9 +1395,9 @@ dependencies = [
[[package]]
name = "quinn-proto"
version = "0.11.10"
version = "0.11.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b820744eb4dc9b57a3398183639c511b5a26d2ed702cedd3febaa1393caa22cc"
checksum = "bcbafbbdbb0f638fe3f35f3c56739f77a8a1d070cb25603226c83339b391472b"
dependencies = [
"bytes",
"getrandom 0.3.2",
@ -1415,9 +1415,9 @@ dependencies = [
[[package]]
name = "quinn-udp"
version = "0.5.11"
version = "0.5.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "541d0f57c6ec747a90738a52741d3221f7960e8ac2f0ff4b1a63680e033b4ab5"
checksum = "ee4e529991f949c5e25755532370b8af5d114acae52326361d68d47af64aa842"
dependencies = [
"cfg_aliases",
"libc",
@ -1489,7 +1489,7 @@ version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom 0.2.15",
"getrandom 0.2.16",
]
[[package]]
@ -1569,7 +1569,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
dependencies = [
"cc",
"cfg-if",
"getrandom 0.2.15",
"getrandom 0.2.16",
"libc",
"untrusted",
"windows-sys 0.52.0",
@ -1609,9 +1609,9 @@ checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
[[package]]
name = "rustix"
version = "1.0.5"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf"
checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266"
dependencies = [
"bitflags",
"errno",
@ -1781,9 +1781,9 @@ dependencies = [
[[package]]
name = "sha2"
version = "0.10.8"
version = "0.10.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
dependencies = [
"cfg-if",
"cpufeatures",
@ -2088,9 +2088,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "syn"
version = "2.0.100"
version = "2.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
dependencies = [
"proc-macro2",
"quote",
@ -2108,9 +2108,9 @@ dependencies = [
[[package]]
name = "synstructure"
version = "0.13.1"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
dependencies = [
"proc-macro2",
"quote",
@ -2258,9 +2258,9 @@ dependencies = [
[[package]]
name = "tokio-util"
version = "0.7.14"
version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b9590b93e6fcc1739458317cccd391ad3955e2bde8913edf6f95f9e65a8f034"
checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df"
dependencies = [
"bytes",
"futures-core",
@ -2271,7 +2271,7 @@ dependencies = [
[[package]]
name = "torn-api"
version = "1.1.1"
version = "1.2.0"
dependencies = [
"bon",
"bytes",
@ -2291,7 +2291,7 @@ dependencies = [
[[package]]
name = "torn-api-codegen"
version = "0.2.1"
version = "0.2.3"
dependencies = [
"heck",
"indexmap",
@ -2582,9 +2582,9 @@ dependencies = [
[[package]]
name = "webpki-roots"
version = "0.26.8"
version = "0.26.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2210b291f7ea53617fbafcc4939f10914214ec15aace5ba62293a668f322c5c9"
checksum = "37493cadf42a2a939ed404698ded7fb378bf301b5011f973361779a3a74f8c93"
dependencies = [
"rustls-pki-types",
]
@ -2937,18 +2937,18 @@ dependencies = [
[[package]]
name = "zerocopy"
version = "0.8.24"
version = "0.8.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879"
checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.24"
version = "0.8.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be"
checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef"
dependencies = [
"proc-macro2",
"quote",

View file

@ -1,7 +1,7 @@
[package]
name = "torn-api-codegen"
authors = ["Pyrit [2111649]"]
version = "0.2.1"
version = "0.2.3"
edition = "2021"
description = "Contains the v2 torn API model descriptions and codegen for the bindings"
license-file = { workspace = true }

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
use heck::{ToSnakeCase, ToUpperCamelCase};
use indexmap::IndexMap;
use proc_macro2::TokenStream;
use quote::{ToTokens, format_ident, quote};
use quote::{format_ident, quote, ToTokens};
use syn::Ident;
use crate::openapi::r#type::OpenApiType;
@ -82,6 +82,7 @@ pub struct Property {
pub required: bool,
pub nullable: bool,
pub r#type: PropertyType,
pub deprecated: bool,
}
impl Property {
@ -105,30 +106,25 @@ impl Property {
name,
description,
required,
deprecated: schema.deprecated,
nullable: false,
}),
OpenApiType {
one_of: Some(types),
..
} => match types.as_slice() {
[
left,
OpenApiType {
r#type: Some("null"),
..
},
] => {
[left, OpenApiType {
r#type: Some("null"),
..
}] => {
let mut inner = Self::from_schema(&name, required, left, schemas)?;
inner.nullable = true;
Some(inner)
}
[
left @ ..,
OpenApiType {
r#type: Some("null"),
..
},
] => {
[left @ .., OpenApiType {
r#type: Some("null"),
..
}] => {
let rest = OpenApiType {
one_of: Some(left.to_owned()),
..schema.clone()
@ -141,9 +137,10 @@ impl Property {
let r#enum = Enum::from_one_of(&name.to_upper_camel_case(), cases)?;
Some(Self {
name,
description: None,
description,
required,
nullable: false,
deprecated: schema.deprecated,
r#type: PropertyType::Enum(r#enum),
})
}
@ -155,9 +152,10 @@ impl Property {
let composite = Object::from_all_of(&name.to_upper_camel_case(), types, schemas)?;
Some(Self {
name,
description: None,
description,
required,
nullable: false,
deprecated: schema.deprecated,
r#type: PropertyType::Nested(Box::new(composite)),
})
}
@ -173,6 +171,7 @@ impl Property {
name,
description,
required,
deprecated: schema.deprecated,
nullable: false,
}),
OpenApiType {
@ -183,6 +182,7 @@ impl Property {
description,
r#type: PropertyType::Ref((*path).to_owned()),
required,
deprecated: schema.deprecated,
nullable: false,
}),
OpenApiType {
@ -197,6 +197,7 @@ impl Property {
description,
required,
nullable: false,
deprecated: schema.deprecated,
r#type: PropertyType::Array(Box::new(inner.r#type)),
})
}
@ -217,6 +218,7 @@ impl Property {
description,
required,
nullable: false,
deprecated: schema.deprecated,
r#type: PropertyType::Primitive(prim),
})
}
@ -245,8 +247,17 @@ impl Property {
ty_inner
};
let deprecated = self.deprecated.then(|| {
let note = self.description.as_ref().map(|d| quote! { note = #d });
quote! {
#[deprecated(#note)]
}
});
Some(quote! {
#desc
#deprecated
#serde_attr
pub #name: #ty
})

View file

@ -1,4 +1,4 @@
use std::{fmt::Write, ops::Deref};
use std::fmt::Write;
use heck::{ToSnakeCase, ToUpperCamelCase};
use indexmap::IndexMap;
@ -40,7 +40,7 @@ pub struct Path {
pub segments: Vec<PathSegment>,
pub name: String,
pub summary: Option<String>,
pub description: String,
pub description: Option<String>,
pub parameters: Vec<PathParameter>,
pub response: PathResponse,
}
@ -63,7 +63,7 @@ impl Path {
}
let summary = schema.get.summary.as_deref().map(ToOwned::to_owned);
let description = schema.get.description.deref().to_owned();
let description = schema.get.description.as_deref().map(ToOwned::to_owned);
let mut params = Vec::with_capacity(schema.get.parameters.len());
for parameter in &schema.get.parameters {
@ -377,7 +377,23 @@ impl Path {
}
};
let doc = match (&self.summary, &self.description) {
(Some(summary), Some(description)) => {
Some(format!("{summary}\n\n# Description\n{description}"))
}
(Some(summary), None) => Some(summary.clone()),
(None, Some(description)) => Some(format!("# Description\n{description}")),
(None, None) => None,
};
let doc = doc.map(|d| {
quote! {
#[doc = #d]
}
});
Some(quote! {
#doc
pub async fn #fn_name<S>(
self,
#(#extra_args)*
@ -487,7 +503,23 @@ impl Path {
quote! { #(#disc_ty),* }
};
let doc = match (&self.summary, &self.description) {
(Some(summary), Some(description)) => {
Some(format!("{summary}\n\n# Description\n{description}"))
}
(Some(summary), None) => Some(summary.clone()),
(None, Some(description)) => Some(format!("# Description\n{description}")),
(None, None) => None,
};
let doc = doc.map(|d| {
quote! {
#[doc = #d]
}
});
Some(quote! {
#doc
pub fn #fn_name<S, I, B>(
self,
ids: I,

View file

@ -50,6 +50,7 @@ impl Scope {
}
Some(quote! {
#[allow(dead_code)]
pub struct #name<E>(E)
where
E: crate::executor::Executor;
@ -65,6 +66,7 @@ impl Scope {
#(#functions)*
}
#[allow(dead_code)]
pub struct #bulk_name<E> where
E: crate::executor::BulkExecutor,
{

View file

@ -33,7 +33,7 @@ impl Union {
let ty_name = format_ident!("{}", variant_name);
variants.push(quote! {
pub fn #accessor_name(&self) -> Result<crate::models::#ty_name, serde_json::Error> {
<crate::models::#ty_name as serde::Deserialize>::deserialize(&self.0)
self.deserialize()
}
});
}
@ -43,6 +43,13 @@ impl Union {
pub struct #name(serde_json::Value);
impl #name {
pub fn deserialize<'de, T>(&'de self) -> Result<T, serde_json::Error>
where
T: serde::Deserialize<'de>,
{
T::deserialize(&self.0)
}
#(#variants)*
}
})

View file

@ -63,7 +63,7 @@ where
#[derive(Debug, Clone, Deserialize)]
pub struct OpenApiPathBody<'a> {
pub summary: Option<Cow<'a, str>>,
pub description: Cow<'a, str>,
pub description: Option<Cow<'a, str>>,
#[serde(borrow, default)]
pub parameters: Vec<OpenApiPathParameter<'a>>,
#[serde(

View file

@ -1,6 +1,6 @@
[package]
name = "torn-api"
version = "1.1.1"
version = "1.2.0"
edition = "2021"
description = "Auto-generated bindings for the v2 torn api"
license-file = { workspace = true }
@ -36,7 +36,7 @@ futures = { version = "0.3", default-features = false, features = [
tokio = { version = "1", features = ["full"] }
[build-dependencies]
torn-api-codegen = { path = "../torn-api-codegen", version = "0.2.1" }
torn-api-codegen = { path = "../torn-api-codegen", version = "0.2.3" }
syn = { workspace = true, features = ["parsing"] }
proc-macro2 = { workspace = true }
prettyplease = "0.2"

View file

@ -62,14 +62,14 @@ pub trait BulkExecutor: Sized {
fn execute<R>(
self,
requests: impl IntoIterator<Item = R>,
) -> impl Stream<Item = (R::Discriminant, Result<ApiResponse, Self::Error>)>
) -> impl Stream<Item = (R::Discriminant, Result<ApiResponse, Self::Error>)> + Unpin
where
R: IntoRequest;
fn fetch_many<R>(
self,
requests: impl IntoIterator<Item = R>,
) -> impl Stream<Item = (R::Discriminant, Result<R::Response, Self::Error>)>
) -> impl Stream<Item = (R::Discriminant, Result<R::Response, Self::Error>)> + Unpin
where
R: IntoRequest,
{
@ -173,7 +173,7 @@ pub trait BulkExecutorExt: BulkExecutor + Sized {
}
#[cfg(feature = "scopes")]
impl<'e, T> BulkExecutorExt for T
impl<T> BulkExecutorExt for T
where
T: BulkExecutor + Sized,
{

View file

@ -28,7 +28,7 @@ pub struct ApiResponse {
}
pub trait IntoRequest: Send {
type Discriminant: Send;
type Discriminant: Send + 'static;
type Response: for<'de> serde::Deserialize<'de> + Send;
fn into_request(self) -> (Self::Discriminant, ApiRequest);
}

View file

@ -569,17 +569,16 @@ where
fn execute<R>(
self,
requests: impl IntoIterator<Item = R>,
) -> impl futures::Stream<Item = (R::Discriminant, Result<ApiResponse, Self::Error>)>
) -> impl futures::Stream<Item = (R::Discriminant, Result<ApiResponse, Self::Error>)> + Unpin
where
R: torn_api::request::IntoRequest,
{
let requests: Vec<_> = requests.into_iter().map(|r| r.into_request()).collect();
self.pool
.execute_bulk_requests(
self.selector.clone(),
requests.into_iter().map(|r| r.into_request()),
)
.execute_bulk_requests(self.selector.clone(), requests)
.into_stream()
.flatten()
.boxed()
}
}
@ -640,22 +639,23 @@ where
fn execute<R>(
self,
requests: impl IntoIterator<Item = R>,
) -> impl futures::Stream<Item = (R::Discriminant, Result<ApiResponse, Self::Error>)>
) -> impl futures::Stream<Item = (R::Discriminant, Result<ApiResponse, Self::Error>)> + Unpin
where
R: torn_api::request::IntoRequest,
{
let requests: Vec<_> = requests.into_iter().map(|r| r.into_request()).collect();
StreamExt::map(
futures::stream::iter(requests).throttle(self.distance),
move |r| {
move |(d, request)| {
let this = self.clone();
async move {
let (d, request) = r.into_request();
let result = this.execute_request(request).await;
(d, result)
}
},
)
.buffer_unordered(25)
.boxed()
}
}