Skip to content

Commit c724528

Browse files
author
Ruben Schmidmeister
committed
Avoid unnecessary allocation
1 parent 6a406a8 commit c724528

File tree

1 file changed

+50
-16
lines changed

1 file changed

+50
-16
lines changed

src/checkstyle.rs

Lines changed: 50 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::fmt::{self, Display};
12
use std::io::{self, Write};
23
use std::path::Path;
34

@@ -35,13 +36,12 @@ where
3536
for mismatch in diff {
3637
for line in mismatch.lines {
3738
// Do nothing with `DiffLine::Context` and `DiffLine::Resulting`.
38-
if let DiffLine::Expected(ref str) = line {
39-
let message = xml_escape_str(str);
39+
if let DiffLine::Expected(message) = line {
4040
write!(
4141
writer,
4242
"<error line=\"{}\" severity=\"warning\" message=\"Should be `{}`\" \
4343
/>",
44-
mismatch.line_number, message
44+
mismatch.line_number, XmlEscaped(&message)
4545
)?;
4646
}
4747
}
@@ -50,19 +50,53 @@ where
5050
Ok(())
5151
}
5252

53-
// Convert special characters into XML entities.
54-
// This is needed for checkstyle output.
55-
fn xml_escape_str(string: &str) -> String {
56-
let mut out = String::new();
57-
for c in string.chars() {
58-
match c {
59-
'<' => out.push_str("&lt;"),
60-
'>' => out.push_str("&gt;"),
61-
'"' => out.push_str("&quot;"),
62-
'\'' => out.push_str("&apos;"),
63-
'&' => out.push_str("&amp;"),
64-
_ => out.push(c),
53+
/// Convert special characters into XML entities.
54+
/// This is needed for checkstyle output.
55+
struct XmlEscaped<'a>(&'a str);
56+
57+
impl<'a> Display for XmlEscaped<'a> {
58+
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
59+
for char in self.0.chars() {
60+
match char {
61+
'<' => write!(formatter, "&lt;"),
62+
'>' => write!(formatter, "&gt;"),
63+
'"' => write!(formatter, "&quot;"),
64+
'\'' => write!(formatter, "&apos;"),
65+
'&' => write!(formatter, "&amp;"),
66+
_ => write!(formatter, "{}", char),
67+
}?;
6568
}
69+
70+
Ok(())
71+
}
72+
}
73+
74+
#[cfg(test)]
75+
mod tests {
76+
use super::*;
77+
78+
#[test]
79+
fn special_characters_are_escaped() {
80+
assert_eq!(
81+
"&lt;&gt;&quot;&apos;&amp;",
82+
format!("{}", XmlEscaped(r#"<>"'&"#)),
83+
);
84+
}
85+
86+
#[test]
87+
fn special_characters_are_escaped_in_string_with_other_characters() {
88+
assert_eq!(
89+
"The quick brown &quot;🦊&quot; jumps &lt;over&gt; the lazy 🐶",
90+
format!(
91+
"{}",
92+
XmlEscaped(r#"The quick brown "🦊" jumps <over> the lazy 🐶"#)
93+
),
94+
);
95+
}
96+
97+
#[test]
98+
fn other_characters_are_not_escaped() {
99+
let string = "The quick brown 🦊 jumps over the lazy 🐶";
100+
assert_eq!(string, format!("{}", XmlEscaped(string)),);
66101
}
67-
out
68102
}

0 commit comments

Comments
 (0)