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 summary / description split on empty lines #947

Merged
merged 1 commit into from
May 23, 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
42 changes: 23 additions & 19 deletions utoipa-gen/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,28 +389,31 @@ impl<'p> ToTokensDiagnostics for Path<'p> {
}
});

let split_comment = self
.doc_comments
.as_ref()
.and_then(|comments| comments.split_first())
.map(|(summary, description)| {
// Skip all whitespace lines
let start_pos = description
.iter()
.position(|s| !s.chars().all(char::is_whitespace));

let trimmed = start_pos
.and_then(|pos| description.get(pos..))
.unwrap_or(description);

(summary, trimmed)
});
let split_comment = self.doc_comments.as_ref().map(|comments| {
let mut split = comments.split(|comment| comment.trim().is_empty());
let summary = split
.by_ref()
.next()
.map(|summary| summary.join("\n"))
.unwrap_or_default();
let description = split.map(|lines| lines.join("\n")).collect::<Vec<_>>();

(summary, description)
});

let operation: Operation = Operation {
deprecated: &self.deprecated,
operation_id,
summary: split_comment.map(|(summary, _)| summary),
description: split_comment.map(|(_, description)| description),
summary: split_comment.as_ref().and_then(|(summary, _)| {
if summary.is_empty() {
None
} else {
Some(summary)
}
}),
description: split_comment
.as_ref()
.map(|(_, description)| description.as_ref()),
parameters: self.path_attr.params.as_ref(),
request_body: self.path_attr.request_body.as_ref(),
responses: self.path_attr.responses.as_ref(),
Expand Down Expand Up @@ -514,7 +517,7 @@ impl ToTokensDiagnostics for Operation<'_> {
}

if let Some(description) = self.description {
let description = description.join("\n");
let description = description.join("\n\n");

if !description.is_empty() {
tokens.extend(quote! {
Expand Down Expand Up @@ -603,6 +606,7 @@ pub trait PathTypeTree {
/// Resolve default content type based on current [`Type`].
fn get_default_content_type(&self) -> &str;

#[allow(unused)]
/// Check whether [`TypeTree`] an option
fn is_option(&self) -> bool;

Expand Down
38 changes: 22 additions & 16 deletions utoipa-gen/tests/path_derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,20 +101,6 @@ test_path_operation! {
derive_path_connect: connect
}

test_api_fn! {
name: test_operation2,
module: derive_path_with_all_info,
operation: post,
path: "/foo/bar/{id}",
params: (("id", description = "Foo bar id")),
operation_id: "foo_bar_id",
tag: "custom_tag";
/// This is test operation description
///
/// Additional info in long description
#[deprecated]
}

macro_rules! api_fn_doc_with_params {
( $method:ident: $path:literal => $( #[$attr:meta] )* $key:ident $name:ident $body:tt ) => {{
#[allow(dead_code)]
Expand Down Expand Up @@ -147,6 +133,26 @@ macro_rules! api_fn_doc_with_params {
}};
}

test_api_fn! {
name: test_operation2,
module: derive_path_with_all_info,
operation: post,
path: "/foo/bar/{id}",
params: (("id", description = "Foo bar id")),
operation_id: "foo_bar_id",
tag: "custom_tag";
/// This is test operation long multiline
/// summary. That need to be correctly split.
///
/// Additional info in long description
///
/// With more info on separate lines
/// containing text.
///
/// Yeah
#[deprecated]
}

#[test]
fn derive_path_with_all_info_success() {
let operation = test_api_fn_doc! {
Expand All @@ -158,8 +164,8 @@ 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#""Additional info in long description""#, "Api fn description"
"summary" = r#""This is test operation description""#, "Api fn summary"
"description" = r#""Additional info in long description\n\nWith more info on separate lines\ncontaining text.\n\nYeah""#, "Api fn description"
"summary" = r#""This is test operation long multiline\nsummary. That need to be correctly split.""#, "Api fn summary"
"operationId" = r#""foo_bar_id""#, "Api fn operation_id"
"tags.[0]" = r#""custom_tag""#, "Api fn tag"

Expand Down
Loading