Skip to content

Commit

Permalink
Fix title on unnamed struct and references (#1101)
Browse files Browse the repository at this point in the history
This commit fixes `title` attribute on unnamed structs having `Vec<T>`
content and fields having `$ref` type.

Fields with `$ref` type to another having `title` attribute will result
`allOf` type containing the `$ref` as item and `title` will be added to
the `allOf`.

Fixes #850
  • Loading branch information
juhaku authored Oct 7, 2024
1 parent dae6ba5 commit 2f09ae4
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 12 deletions.
1 change: 1 addition & 0 deletions utoipa-gen/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

### Fixed

* Fix `title` on unnamed struct and references (https://github.com/juhaku/utoipa/pull/1101)
* Fix generic references (https://github.com/juhaku/utoipa/pull/1097)
* Fix non generic root generic references (https://github.com/juhaku/utoipa/pull/1095)
* Fix option wrapped tailing query parameters (https://github.com/juhaku/utoipa/pull/1089)
Expand Down
24 changes: 12 additions & 12 deletions utoipa-gen/src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -901,6 +901,7 @@ impl ComponentSchema {
let nullable: Option<Nullable> =
pop_feature!(features => Feature::Nullable(_)).into_inner();
let default = pop_feature!(features => Feature::Default(_));
let title = pop_feature!(features => Feature::Title(_));
let deprecated = pop_feature!(features => Feature::Deprecated(_)).try_to_token_stream()?;

let child = type_tree
Expand Down Expand Up @@ -980,10 +981,8 @@ impl ComponentSchema {
tokens.extend(min_items.to_token_stream())
}

if let Some(default) = default {
tokens.extend(default.to_token_stream())
}

default.to_tokens(tokens)?;
title.to_tokens(tokens)?;
example.to_tokens(tokens)?;
xml.to_tokens(tokens)?;

Expand Down Expand Up @@ -1092,10 +1091,12 @@ impl ComponentSchema {

object_schema_reference.name = quote! { String::from(#name_tokens) };

if is_inline {
let default = pop_feature!(features => Feature::Default(_));
let default_tokens = as_tokens_or_diagnostics!(&default);
let default = pop_feature!(features => Feature::Default(_));
let default_tokens = as_tokens_or_diagnostics!(&default);
let title = pop_feature!(features => Feature::Title(_));
let title_tokens = as_tokens_or_diagnostics!(&title);

if is_inline {
let items_tokens = if let Some(children) = &type_tree.children {
schema_references.extend(Self::compose_child_references(children));

Expand All @@ -1112,11 +1113,12 @@ impl ComponentSchema {
object_schema_reference.tokens = items_tokens.clone();
object_schema_reference.references = quote! { <#type_path as utoipa::__dev::SchemaReferences>::schemas(schemas) };

let schema = if default.is_some() || nullable {
let schema = if default.is_some() || nullable || title.is_some() {
quote_spanned! {type_path.span()=>
utoipa::openapi::schema::AllOfBuilder::new()
#nullable_item
.item(#items_tokens)
#title_tokens
#default_tokens
}
} else {
Expand All @@ -1125,9 +1127,6 @@ impl ComponentSchema {

schema.to_tokens(tokens);
} else {
let default = pop_feature!(features => Feature::Default(_));
let default_tokens = as_tokens_or_diagnostics!(&default);

let index = container.generics.get_generic_type_param_index(type_tree);
// only set schema references for concrete non generic types
if index.is_none() {
Expand Down Expand Up @@ -1164,14 +1163,15 @@ impl ComponentSchema {
// TODO: refs support `summary` field but currently there is no such field
// on schemas more over there is no way to distinct the `summary` from
// `description` of the ref. Should we consider supporting the summary?
let schema = if default.is_some() || nullable {
let schema = if default.is_some() || nullable || title.is_some() {
composed_or_ref(quote_spanned! {type_path.span()=>
utoipa::openapi::schema::AllOfBuilder::new()
#nullable_item
.item(utoipa::openapi::schema::RefBuilder::new()
#description_stream
.ref_location_from_schema_name(#name_tokens)
)
#title_tokens
#default_tokens
})
} else {
Expand Down
44 changes: 44 additions & 0 deletions utoipa-gen/tests/schema_derive_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5707,3 +5707,47 @@ fn derive_schema_with_ignored_field() {
})
)
}

#[test]
fn derive_schema_unnamed_title() {
#![allow(unused)]

let value = api_doc! {
#[schema(title = "This is vec title")]
struct SchemaIgnoredField (Vec<String>);
};

assert_json_eq!(
value,
json!({
"title": "This is vec title",
"items": {
"type": "string"
},
"type": "array"
})
);

#[derive(ToSchema)]
enum UnnamedEnum {
One,
Two,
}

let enum_value = api_doc! {
#[schema(title = "This is enum ref title")]
struct SchemaIgnoredField (UnnamedEnum);
};

assert_json_eq!(
enum_value,
json!({
"title": "This is enum ref title",
"allOf": [
{
"$ref": "#/components/schemas/UnnamedEnum"
}
],
})
)
}

0 comments on commit 2f09ae4

Please sign in to comment.