diff options
Diffstat (limited to 'src/tools/rustfmt/src/attr/doc_comment.rs')
-rw-r--r-- | src/tools/rustfmt/src/attr/doc_comment.rs | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/src/tools/rustfmt/src/attr/doc_comment.rs b/src/tools/rustfmt/src/attr/doc_comment.rs new file mode 100644 index 000000000..f653a12a8 --- /dev/null +++ b/src/tools/rustfmt/src/attr/doc_comment.rs @@ -0,0 +1,83 @@ +use crate::comment::CommentStyle; +use std::fmt::{self, Display}; + +/// Formats a string as a doc comment using the given [`CommentStyle`]. +#[derive(new)] +pub(super) struct DocCommentFormatter<'a> { + literal: &'a str, + style: CommentStyle<'a>, +} + +impl Display for DocCommentFormatter<'_> { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + let opener = self.style.opener().trim_end(); + let mut lines = self.literal.lines().peekable(); + + // Handle `#[doc = ""]`. + if lines.peek().is_none() { + return write!(formatter, "{}", opener); + } + + while let Some(line) = lines.next() { + let is_last_line = lines.peek().is_none(); + if is_last_line { + write!(formatter, "{}{}", opener, line)?; + } else { + writeln!(formatter, "{}{}", opener, line)?; + } + } + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn literal_controls_leading_spaces() { + test_doc_comment_is_formatted_correctly( + " Lorem ipsum", + "/// Lorem ipsum", + CommentStyle::TripleSlash, + ); + } + + #[test] + fn single_line_doc_comment_is_formatted_correctly() { + test_doc_comment_is_formatted_correctly( + "Lorem ipsum", + "///Lorem ipsum", + CommentStyle::TripleSlash, + ); + } + + #[test] + fn multi_line_doc_comment_is_formatted_correctly() { + test_doc_comment_is_formatted_correctly( + "Lorem ipsum\nDolor sit amet", + "///Lorem ipsum\n///Dolor sit amet", + CommentStyle::TripleSlash, + ); + } + + #[test] + fn whitespace_within_lines_is_preserved() { + test_doc_comment_is_formatted_correctly( + " Lorem ipsum \n Dolor sit amet ", + "/// Lorem ipsum \n/// Dolor sit amet ", + CommentStyle::TripleSlash, + ); + } + + fn test_doc_comment_is_formatted_correctly( + literal: &str, + expected_comment: &str, + style: CommentStyle<'_>, + ) { + assert_eq!( + expected_comment, + format!("{}", DocCommentFormatter::new(literal, style)) + ); + } +} |