diff --git a/src/checkstyle.rs b/src/checkstyle.rs
index 79c59bb1e8c..557ab37703f 100644
--- a/src/checkstyle.rs
+++ b/src/checkstyle.rs
@@ -1,3 +1,4 @@
+use std::fmt::{self, Display};
use std::io::{self, Write};
use std::path::Path;
@@ -35,13 +36,12 @@ where
for mismatch in diff {
for line in mismatch.lines {
// Do nothing with `DiffLine::Context` and `DiffLine::Resulting`.
- if let DiffLine::Expected(ref str) = line {
- let message = xml_escape_str(str);
+ if let DiffLine::Expected(message) = line {
write!(
writer,
"",
- mismatch.line_number, message
+ mismatch.line_number, XmlEscaped(&message)
)?;
}
}
@@ -50,19 +50,53 @@ where
Ok(())
}
-// Convert special characters into XML entities.
-// This is needed for checkstyle output.
-fn xml_escape_str(string: &str) -> String {
- let mut out = String::new();
- for c in string.chars() {
- match c {
- '<' => out.push_str("<"),
- '>' => out.push_str(">"),
- '"' => out.push_str("""),
- '\'' => out.push_str("'"),
- '&' => out.push_str("&"),
- _ => out.push(c),
+/// Convert special characters into XML entities.
+/// This is needed for checkstyle output.
+struct XmlEscaped<'a>(&'a str);
+
+impl<'a> Display for XmlEscaped<'a> {
+ fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ for char in self.0.chars() {
+ match char {
+ '<' => write!(formatter, "<"),
+ '>' => write!(formatter, ">"),
+ '"' => write!(formatter, """),
+ '\'' => write!(formatter, "'"),
+ '&' => write!(formatter, "&"),
+ _ => write!(formatter, "{}", char),
+ }?;
}
+
+ Ok(())
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn special_characters_are_escaped() {
+ assert_eq!(
+ "<>"'&",
+ format!("{}", XmlEscaped(r#"<>"'&"#)),
+ );
+ }
+
+ #[test]
+ fn special_characters_are_escaped_in_string_with_other_characters() {
+ assert_eq!(
+ "The quick brown "🦊" jumps <over> the lazy 🐶",
+ format!(
+ "{}",
+ XmlEscaped(r#"The quick brown "🦊" jumps the lazy 🐶"#)
+ ),
+ );
+ }
+
+ #[test]
+ fn other_characters_are_not_escaped() {
+ let string = "The quick brown 🦊 jumps over the lazy 🐶";
+ assert_eq!(string, format!("{}", XmlEscaped(string)),);
}
- out
}