rustfmt_nightly/attr/
doc_comment.rs
1use crate::comment::CommentStyle;
2use std::fmt::{self, Display};
3
4pub(super) struct DocCommentFormatter<'a> {
6 literal: &'a str,
7 style: CommentStyle<'a>,
8}
9
10impl<'a> DocCommentFormatter<'a> {
11 pub(super) const fn new(literal: &'a str, style: CommentStyle<'a>) -> Self {
12 Self { literal, style }
13 }
14}
15
16impl Display for DocCommentFormatter<'_> {
17 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
18 let opener = self.style.opener().trim_end();
19 let mut lines = self.literal.lines().peekable();
20
21 if lines.peek().is_none() {
23 return write!(formatter, "{opener}");
24 }
25
26 while let Some(line) = lines.next() {
27 let is_last_line = lines.peek().is_none();
28 if is_last_line {
29 write!(formatter, "{opener}{line}")?;
30 } else {
31 writeln!(formatter, "{opener}{line}")?;
32 }
33 }
34 Ok(())
35 }
36}
37
38#[cfg(test)]
39mod tests {
40 use super::*;
41
42 #[test]
43 fn literal_controls_leading_spaces() {
44 test_doc_comment_is_formatted_correctly(
45 " Lorem ipsum",
46 "/// Lorem ipsum",
47 CommentStyle::TripleSlash,
48 );
49 }
50
51 #[test]
52 fn single_line_doc_comment_is_formatted_correctly() {
53 test_doc_comment_is_formatted_correctly(
54 "Lorem ipsum",
55 "///Lorem ipsum",
56 CommentStyle::TripleSlash,
57 );
58 }
59
60 #[test]
61 fn multi_line_doc_comment_is_formatted_correctly() {
62 test_doc_comment_is_formatted_correctly(
63 "Lorem ipsum\nDolor sit amet",
64 "///Lorem ipsum\n///Dolor sit amet",
65 CommentStyle::TripleSlash,
66 );
67 }
68
69 #[test]
70 fn whitespace_within_lines_is_preserved() {
71 test_doc_comment_is_formatted_correctly(
72 " Lorem ipsum \n Dolor sit amet ",
73 "/// Lorem ipsum \n/// Dolor sit amet ",
74 CommentStyle::TripleSlash,
75 );
76 }
77
78 fn test_doc_comment_is_formatted_correctly(
79 literal: &str,
80 expected_comment: &str,
81 style: CommentStyle<'_>,
82 ) {
83 assert_eq!(
84 expected_comment,
85 format!("{}", DocCommentFormatter::new(literal, style))
86 );
87 }
88}