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

Skip first doc comment line in path macro description expansion #881

Merged
merged 1 commit into from
May 1, 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 utoipa-gen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -657,12 +657,12 @@ pub fn derive_to_schema(input: TokenStream) -> TokenStream {
/// `#[deprecated = "There is better way to do this"]` the reason would not render in OpenAPI spec.
///
/// Doc comment at decorated function will be used for _`description`_ and _`summary`_ of the path.
/// First line of the doc comment will be used as the _`summary`_ and the whole doc comment will be
/// First line of the doc comment will be used as the _`summary`_ while the remaining lines will be
/// used as _`description`_.
/// ```rust
/// /// This is a summary of the operation
/// ///
/// /// All lines of the doc comment will be included to operation description.
/// /// The rest of the doc comment will be included to operation description.
/// #[utoipa::path(get, path = "/operation")]
/// fn operation() {}
/// ```
Expand Down
26 changes: 20 additions & 6 deletions utoipa-gen/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,14 +376,28 @@ impl<'p> ToTokens 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 operation: Operation = Operation {
deprecated: &self.deprecated,
operation_id,
summary: self
.doc_comments
.as_ref()
.and_then(|comments| comments.iter().next()),
description: self.doc_comments.as_ref(),
summary: split_comment.map(|(summary, _)| summary),
description: split_comment.map(|(_, description)| description),
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 @@ -427,7 +441,7 @@ impl<'p> ToTokens for Path<'p> {
struct Operation<'a> {
operation_id: Expr,
summary: Option<&'a String>,
description: Option<&'a Vec<String>>,
description: Option<&'a [String]>,
deprecated: &'a Option<bool>,
parameters: &'a Vec<Parameter<'a>>,
request_body: Option<&'a RequestBody<'a>>,
Expand Down
4 changes: 2 additions & 2 deletions utoipa-gen/tests/path_derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,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""#, "Api fn description"
"description" = r#""Additional 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 @@ -224,7 +224,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#"null"#, "Api operation deprecated"
"description" = r#""This is test operation\n\nThis is long description for test operation""#, "Api operation description"
"description" = r#""This 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
Loading