Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix async impl Responder. Bump msrv to 1.81 #131

Merged
merged 2 commits into from
Sep 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ actix-web-lab = "0.20"
assert-json-diff = "2.0.2"
convert_case = "0.6"
darling = "0.20"
futures-core = "0.3.28"
futures-core = "0.3"
futures-util = "0.3"
indexmap = "2"
log = "0.4.20"
num_cpus = "1.16"
Expand Down Expand Up @@ -69,7 +70,6 @@ unused_import_braces = "warn"
unused-lifetimes = "warn"
unused_macro_rules = "warn"
unused_qualifications = "warn"
unused_tuple_struct_fields = "warn"

[workspace.lints.clippy]
bool_to_int_with_if = "warn"
Expand Down
1 change: 0 additions & 1 deletion apistos-gen-test/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#![allow(deprecated)]
#![allow(dead_code)]
#![allow(clippy::expect_used)]
#![allow(unused_tuple_struct_fields)]

#[cfg(test)]
pub(crate) mod tests;
Expand Down
2 changes: 2 additions & 0 deletions apistos-gen-test/src/tests/api_error_derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::collections::{BTreeMap, HashSet};
#[test]
#[allow(dead_code)]
fn api_component_derive() {
#[allow(clippy::duplicated_attributes)]
#[derive(ApiErrorComponent)]
#[openapi_error(
status(code = 403),
Expand Down Expand Up @@ -59,6 +60,7 @@ fn api_component_with_schema() {
code: String,
}

#[allow(clippy::duplicated_attributes)]
#[derive(ApiErrorComponent)]
#[openapi_error(status(code = 403), status(code = 409, description = "Too many requests"))]
enum ErrorResponse {
Expand Down
67 changes: 67 additions & 0 deletions apistos-gen-test/src/tests/api_operation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ mod test_models {
}
}

#[allow(clippy::duplicated_attributes)]
#[derive(Serialize, Deserialize, Debug, Clone, ApiErrorComponent)]
#[openapi_error(status(code = 401), status(code = 403), status(code = 404), status(code = 405))]
pub(crate) enum MultipleErrorResponse {
Expand Down Expand Up @@ -216,6 +217,20 @@ fn api_operation_impl_responder() {
HttpResponse::Ok()
}

#[allow(clippy::todo, clippy::unused_async)]
async fn plop() {
todo!()
}

/// Add a new pet to the store
/// Add a new pet to the store
/// Plop
#[api_operation(tag = "pet")]
pub(crate) async fn test_async(_body: Json<test_models::Test>) -> impl Responder {
plop().await;
HttpResponse::Ok()
}

let components = __openapi_test::components();
// only one component here because: error does not have schema and Test is used both for query and response
assert_eq!(components.len(), 1);
Expand Down Expand Up @@ -267,6 +282,58 @@ fn api_operation_impl_responder() {
]
})
);

let components = __openapi_test_async::components();
// only one component here because: error does not have schema and Test is used both for query and response
assert_eq!(components.len(), 1);
let components = serde_json::to_value(components).expect("Unable to serialize as Json");

let operation = __openapi_test_async::operation();
let operation = serde_json::to_value(operation).expect("Unable to serialize as Json");

assert_json_eq!(
components,
json!([
{
"schemas": {
"Test": {
"properties": {
"test": {
"type": "string"
}
},
"required": [
"test"
],
"title": "Test",
"type": "object"
}
}
}
])
);
assert_json_eq!(
operation,
json!({
"deprecated": false,
"description": "Add a new pet to the store\\\nPlop",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Test"
}
}
},
"required": true
},
"responses": {},
"summary": "Add a new pet to the store",
"tags": [
"pet"
]
})
);
}

#[test]
Expand Down
6 changes: 5 additions & 1 deletion apistos-gen/src/internal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,11 @@ pub(crate) fn gen_item_ast(

let block = item_ast.block;
let inner_handler = if is_responder {
quote!(core::future::ready(apistos::actix::ResponderWrapper((move || #block)())))
quote!({
use apistos::FutureExt;
#[expect(async_yields_async)]
(move || { async move #block })().map(apistos::actix::ResponderWrapper)
})
} else if is_impl_trait {
quote!((move || #block)())
} else {
Expand Down
2 changes: 1 addition & 1 deletion apistos-gen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ pub fn api_operation(attr: TokenStream, item: TokenStream) -> TokenStream {

let operation_attribute = parse_openapi_operation_attrs(&attr_args);

let default_span = proc_macro2::Span::call_site();
let default_span = Span::call_site();
let item_ast = match syn::parse::<ItemFn>(item) {
Ok(v) => v,
Err(e) => abort!(e.span(), format!("{e}")),
Expand Down
4 changes: 2 additions & 2 deletions apistos-models/src/paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ pub struct Example {
/// Long description for the example. [CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation.
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
/// Embedded literal example. The `value` field and `externalValue field are mutually exclusive. To represent examples of media types that cannot naturally represented in JSON or YAML, use a string value to contain the example, escaping where necessary.
/// Embedded literal example. The `value` field and `externalValue` field are mutually exclusive. To represent examples of media types that cannot naturally represented in JSON or YAML, use a string value to contain the example, escaping where necessary.
#[serde(flatten)]
pub value: ExampleValue,
/// This object MAY be extended with [Specification Extensions](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specification-extensions).
Expand Down Expand Up @@ -445,6 +445,6 @@ pub enum AnyOrExpression {
pub enum OperationIdentifier {
/// A relative or absolute URI reference to an OAS operation. This field is mutually exclusive of the `operationId` field, and MUST point to an [Operation Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object). Relative `operationRef` values MAY be used to locate an existing [Operation Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object) in the OpenAPI definition.
OperationRef(String),
/// The name of an existing, resolvable OAS operation, as defined with a unique `operationId. This field is mutually exclusive of the `operationRef` field.
/// The name of an existing, resolvable OAS operation, as defined with a unique `operationId`. This field is mutually exclusive of the `operationRef` field.
OperationId(String),
}
6 changes: 3 additions & 3 deletions apistos-models/src/security.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ pub struct OauthImplicit {
/// The URL to be used for obtaining refresh tokens. This MUST be in the form of a URL.
#[serde(skip_serializing_if = "Option::is_none")]
pub refresh_url: Option<String>,
/// The available scopes for the OAuth2 security scheme. A map between the scope name and a short description for it. The map MAY be empty.
/// The available scopes for the `OAuth2` security scheme. A map between the scope name and a short description for it. The map MAY be empty.
pub scopes: BTreeMap<String, String>,
}

Expand All @@ -127,14 +127,14 @@ pub struct OauthToken {
/// The URL to be used for obtaining refresh tokens. This MUST be in the form of a URL.
#[serde(skip_serializing_if = "Option::is_none")]
pub refresh_url: Option<String>,
/// The available scopes for the OAuth2 security scheme. A map between the scope name and a short description for it. The map MAY be empty.
/// The available scopes for the `OAuth2` security scheme. A map between the scope name and a short description for it. The map MAY be empty.
pub scopes: BTreeMap<String, String>,
}

#[derive(Serialize, Clone, Debug, Default)]
#[cfg_attr(any(test, feature = "deserialize"), derive(serde::Deserialize, PartialEq))]
#[serde(rename_all = "camelCase")]
pub struct OpenIdConnect {
/// OpenId Connect URL to discover OAuth2 configuration values. This MUST be in the form of a URL.
/// `OpenId` Connect URL to discover `OAuth2` configuration values. This MUST be in the form of a URL.
pub open_id_connect_url: String,
}
2 changes: 1 addition & 1 deletion apistos-shuttle/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ async fn actix_web() -> ShuttleApistosActixWeb<impl FnOnce(&mut ServiceConfig) +
> Default features are disabled for `shuttle-runtime` to avoid pulling [colored](https://github.com/colored-rs/colored)
> which as a license considered as
> copyleft by cargo-deny.
> To implement your own tracing, please visit https://docs.shuttle.rs/configuration/logs
> To implement your own tracing, please visit <https://docs.shuttle.rs/configuration/logs>

### About us

Expand Down
1 change: 1 addition & 0 deletions apistos/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ license.workspace = true
[dependencies]
actix-service = { workspace = true }
actix-web = { workspace = true }
futures-util = { workspace = true }
indexmap = { workspace = true }
log = { workspace = true }
md5 = { workspace = true }
Expand Down
1 change: 1 addition & 0 deletions apistos/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ pub use apistos_redoc::RedocConfig;
pub use apistos_scalar::ScalarConfig;
#[cfg(feature = "swagger-ui")]
pub use apistos_swagger_ui::SwaggerUIConfig;
pub use futures_util::future::FutureExt;

mod internal;

Expand Down
5 changes: 3 additions & 2 deletions apistos/tests/default_parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ async fn default_parameters() {
plap: String,
}

#[allow(unused_tuple_struct_fields)]
#[allow(dead_code)]
#[derive(Clone, Debug, JsonSchema, ApiHeader)]
#[openapi_header(
name = "X-Env-Complex",
Expand All @@ -59,7 +59,7 @@ async fn default_parameters() {
)]
struct SomeComplexHeader(TestHeaderStruct);

#[allow(unused_tuple_struct_fields)]
#[allow(dead_code)]
#[derive(Clone, Debug, JsonSchema, ApiHeader)]
#[openapi_header(
name = "X-Env",
Expand Down Expand Up @@ -182,6 +182,7 @@ use apistos_rapidoc as _;
use apistos_redoc as _;
use apistos_scalar as _;
use apistos_swagger_ui as _;
use futures_util as _;
use garde_actix_web as _;
use indexmap as _;
use log as _;
Expand Down
1 change: 1 addition & 0 deletions apistos/tests/operation_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ use apistos_rapidoc as _;
use apistos_redoc as _;
use apistos_scalar as _;
use apistos_swagger_ui as _;
use futures_util as _;
use garde_actix_web as _;
use indexmap as _;
use log as _;
Expand Down
1 change: 1 addition & 0 deletions apistos/tests/operations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ use apistos_rapidoc as _;
use apistos_redoc as _;
use apistos_scalar as _;
use apistos_swagger_ui as _;
use futures_util as _;
use garde_actix_web as _;
use indexmap as _;
use log as _;
Expand Down
1 change: 1 addition & 0 deletions apistos/tests/parametric_handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ use apistos_rapidoc as _;
use apistos_redoc as _;
use apistos_scalar as _;
use apistos_swagger_ui as _;
use futures_util as _;
use garde_actix_web as _;
use indexmap as _;
use log as _;
Expand Down
1 change: 1 addition & 0 deletions apistos/tests/path_parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ use apistos_rapidoc as _;
use apistos_redoc as _;
use apistos_scalar as _;
use apistos_swagger_ui as _;
use futures_util as _;
use garde_actix_web as _;
use indexmap as _;
use log as _;
Expand Down
1 change: 1 addition & 0 deletions apistos/tests/query_parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ use apistos_rapidoc as _;
use apistos_redoc as _;
use apistos_scalar as _;
use apistos_swagger_ui as _;
use futures_util as _;
use indexmap as _;
use log as _;
use md5 as _;
Expand Down
1 change: 1 addition & 0 deletions apistos/tests/routing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ use apistos_rapidoc as _;
use apistos_redoc as _;
use apistos_scalar as _;
use apistos_swagger_ui as _;
use futures_util as _;
use garde_actix_web as _;
use indexmap as _;
use log as _;
Expand Down
1 change: 1 addition & 0 deletions apistos/tests/tags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ use apistos_rapidoc as _;
use apistos_redoc as _;
use apistos_scalar as _;
use apistos_swagger_ui as _;
use futures_util as _;
use garde_actix_web as _;
use indexmap as _;
use log as _;
Expand Down
2 changes: 1 addition & 1 deletion rust-toolchain
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.75.0
1.81.0