Skip to content

Commit

Permalink
Chore refine description attribute (#373)
Browse files Browse the repository at this point in the history
Unify the description attribute definition across `ToSchema` and
`#[utoipa::path(...)]` attribute macro.
  • Loading branch information
juhaku authored Nov 26, 2022
1 parent 67b9585 commit 65842b9
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 53 deletions.
10 changes: 4 additions & 6 deletions utoipa-gen/src/component/into_params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,12 +297,10 @@ impl ToTokens for Param<'_> {
if let Some(deprecated) = super::get_deprecated(&field.attrs) {
tokens.extend(quote! { .deprecated(Some(#deprecated)) });
}
let attributes = CommentAttributes::from_attributes(&field.attrs);
if !attributes.is_empty() {
let comment = attributes.join("\n");
tokens.extend(quote! {
.description(Some(#comment))
})

let description = CommentAttributes::from_attributes(&field.attrs).as_formatted_string();
if !description.is_empty() {
tokens.extend(quote! { .description(Some(#description))})
}

let component = value_type
Expand Down
56 changes: 21 additions & 35 deletions utoipa-gen/src/component/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,11 +307,10 @@ impl ToTokens for NamedStructSchema<'_> {
tokens.extend(struct_features.to_token_stream())
}

let attributes = CommentAttributes::from_attributes(self.attributes);
if !attributes.is_empty() {
let comment = attributes.join("\n");
let description = CommentAttributes::from_attributes(self.attributes).as_formatted_string();
if !description.is_empty() {
tokens.extend(quote! {
.description(Some(#comment))
.description(Some(#description))
})
}
}
Expand Down Expand Up @@ -433,14 +432,11 @@ impl ToTokens for UnnamedStructSchema<'_> {
}
};

let attributes = CommentAttributes::from_attributes(self.attributes);
if !attributes.is_empty() {
let comment = attributes.join("\n");
if !is_object {
tokens.extend(quote! {
.description(Some(#comment))
})
}
let description = CommentAttributes::from_attributes(self.attributes).as_formatted_string();
if !description.is_empty() && !is_object {
tokens.extend(quote! {
.description(Some(#description))
})
}

if fields_len > 1 {
Expand Down Expand Up @@ -545,11 +541,10 @@ impl ToTokens for EnumSchemaType<'_> {
tokens.extend(quote! { .deprecated(Some(#deprecated)) });
}

let attributes = CommentAttributes::from_attributes(attributes);
if !attributes.is_empty() {
let comment = attributes.join("\n");
let description = CommentAttributes::from_attributes(attributes).as_formatted_string();
if !description.is_empty() {
tokens.extend(quote! {
.description(Some(#comment))
.description(Some(#description))
})
}
}
Expand Down Expand Up @@ -1080,16 +1075,11 @@ impl ToTokens for SchemaProperty<'_> {
tokens.extend(example.to_token_stream());
}

if let Some(description) = self.comments.and_then(|attributes| {
if attributes.is_empty() {
None
} else {
Some(attributes.join("\n"))
if let Some(description) = self.comments.map(CommentAttributes::as_formatted_string)
{
if !description.is_empty() {
tokens.extend(quote! { .description(Some(#description))})
}
}) {
tokens.extend(quote! {
.description(Some(#description))
})
}
}
Some(GenericType::Vec) => {
Expand Down Expand Up @@ -1164,17 +1154,13 @@ impl ToTokens for SchemaProperty<'_> {
})
}

if let Some(description) = self.comments.and_then(|attributes| {
if attributes.is_empty() {
None
} else {
Some(attributes.join("\n"))
if let Some(description) =
self.comments.map(CommentAttributes::as_formatted_string)
{
if !description.is_empty() {
tokens.extend(quote! {.description(Some(#description))})
}
}) {
tokens.extend(quote! {
.description(Some(#description))
})
}
};

if let Some(deprecated) = self.deprecated {
tokens.extend(quote! { .deprecated(Some(#deprecated)) });
Expand Down
5 changes: 5 additions & 0 deletions utoipa-gen/src/doc_comment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ impl CommentAttributes {
_ => abort_call_site!("Exected only Meta::NameValue type"),
}
}

/// Returns found `doc comments` as formatted `String` joining them all with `\n` _(new line)_.
pub(crate) fn as_formatted_string(&self) -> String {
self.join("\n")
}
}

impl Deref for CommentAttributes {
Expand Down
14 changes: 6 additions & 8 deletions utoipa-gen/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -555,15 +555,13 @@ impl ToTokens for Operation<'_> {
}

if let Some(description) = self.description {
let description = description
.iter()
.map(|comment| format!("{}\n", comment))
.collect::<Vec<String>>()
.join("");
let description = description.join("\n");

tokens.extend(quote! {
.description(Some(#description))
})
if !description.is_empty() {
tokens.extend(quote! {
.description(Some(#description))
})
}
}

self.parameters
Expand Down
5 changes: 2 additions & 3 deletions utoipa-gen/tests/path_derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ fn derive_path_with_all_info_success() {
common::assert_json_array_len(operation.pointer("/parameters").unwrap(), 1);
assert_value! {operation=>
"deprecated" = r#"true"#, "Api fn deprecated status"
"description" = r#""This is test operation description\n\nAdditional info in long description\n""#, "Api fn description"
"description" = r#""This is test operation description\n\nAdditional info in long description""#, "Api fn description"
"summary" = r#""This is test operation description""#, "Api fn summary"
"operationId" = r#""foo_bar_id""#, "Api fn operation_id"
"tags.[0]" = r#""custom_tag""#, "Api fn tag"
Expand Down Expand Up @@ -154,7 +154,6 @@ fn derive_path_with_defaults_success() {

assert_value! {operation=>
"deprecated" = r#"false"#, "Api fn deprecated status"
"description" = r#""""#, "Api fn description"
"operationId" = r#""test_operation3""#, "Api fn operation_id"
"tags.[0]" = r#""derive_path_with_defaults""#, "Api fn tag"
"parameters" = r#"null"#, "Api parameters"
Expand Down Expand Up @@ -191,7 +190,7 @@ fn derive_path_with_extra_attributes_without_nested_module() {
common::assert_json_array_len(operation.pointer("/parameters").unwrap(), 2);
assert_value! {operation=>
"deprecated" = r#"false"#, "Api operation deprecated"
"description" = r#""This is test operation\n\nThis is long description for test operation\n""#, "Api operation description"
"description" = r#""This is test operation\n\nThis is long description for test operation""#, "Api operation description"
"operationId" = r#""get_foos_by_id_since""#, "Api operation operation_id"
"summary" = r#""This is test operation""#, "Api operation summary"
"tags.[0]" = r#""crate""#, "Api operation tag"
Expand Down
1 change: 0 additions & 1 deletion utoipa-gen/tests/path_response_derive_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,6 @@ fn derive_response_body_inline_schema_component() {
doc,
json!({
"deprecated": false,
"description": "",
"operationId": "get_foo",
"responses": {
"200": {
Expand Down

0 comments on commit 65842b9

Please sign in to comment.