]> git.proxmox.com Git - rustc.git/blobdiff - src/tools/rustfmt/src/attr/doc_comment.rs
Update upstream source from tag 'upstream/1.52.1+dfsg1'
[rustc.git] / src / tools / rustfmt / src / attr / doc_comment.rs
diff --git a/src/tools/rustfmt/src/attr/doc_comment.rs b/src/tools/rustfmt/src/attr/doc_comment.rs
new file mode 100644 (file)
index 0000000..c3dcb84
--- /dev/null
@@ -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))
+        );
+    }
+}