Skip to content

Commit f7423f0

Browse files
committed
de-dup escaping logic
1 parent fd4cd68 commit f7423f0

File tree

1 file changed

+30
-48
lines changed

1 file changed

+30
-48
lines changed

src/librustdoc/html/escape.rs

+30-48
Original file line numberDiff line numberDiff line change
@@ -7,37 +7,41 @@ use std::fmt;
77

88
use unicode_segmentation::UnicodeSegmentation;
99

10+
#[inline(always)]
11+
fn escape(s: &str, mut w: impl fmt::Write, escape_quotes: bool) -> fmt::Result {
12+
// Because the internet is always right, turns out there's not that many
13+
// characters to escape: http://stackoverflow.com/questions/7381974
14+
let pile_o_bits = s;
15+
let mut last = 0;
16+
for (i, ch) in s.char_indices() {
17+
let s = match ch {
18+
'>' => ">",
19+
'<' => "&lt;",
20+
'&' => "&amp;",
21+
'\'' if escape_quotes => "&#39;",
22+
'"' if escape_quotes => "&quot;",
23+
_ => continue,
24+
};
25+
w.write_str(&pile_o_bits[last..i])?;
26+
w.write_str(s)?;
27+
// NOTE: we only expect single byte characters here - which is fine as long as we
28+
// only match single byte characters
29+
last = i + 1;
30+
}
31+
32+
if last < s.len() {
33+
w.write_str(&pile_o_bits[last..])?;
34+
}
35+
Ok(())
36+
}
37+
1038
/// Wrapper struct which will emit the HTML-escaped version of the contained
1139
/// string when passed to a format string.
1240
pub(crate) struct Escape<'a>(pub &'a str);
1341

1442
impl fmt::Display for Escape<'_> {
1543
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
16-
// Because the internet is always right, turns out there's not that many
17-
// characters to escape: http://stackoverflow.com/questions/7381974
18-
let Escape(s) = *self;
19-
let pile_o_bits = s;
20-
let mut last = 0;
21-
for (i, ch) in s.char_indices() {
22-
let s = match ch {
23-
'>' => "&gt;",
24-
'<' => "&lt;",
25-
'&' => "&amp;",
26-
'\'' => "&#39;",
27-
'"' => "&quot;",
28-
_ => continue,
29-
};
30-
fmt.write_str(&pile_o_bits[last..i])?;
31-
fmt.write_str(s)?;
32-
// NOTE: we only expect single byte characters here - which is fine as long as we
33-
// only match single byte characters
34-
last = i + 1;
35-
}
36-
37-
if last < s.len() {
38-
fmt.write_str(&pile_o_bits[last..])?;
39-
}
40-
Ok(())
44+
escape(self.0, fmt, true)
4145
}
4246
}
4347

@@ -51,29 +55,7 @@ pub(crate) struct EscapeBodyText<'a>(pub &'a str);
5155

5256
impl fmt::Display for EscapeBodyText<'_> {
5357
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
54-
// Because the internet is always right, turns out there's not that many
55-
// characters to escape: http://stackoverflow.com/questions/7381974
56-
let EscapeBodyText(s) = *self;
57-
let pile_o_bits = s;
58-
let mut last = 0;
59-
for (i, ch) in s.char_indices() {
60-
let s = match ch {
61-
'>' => "&gt;",
62-
'<' => "&lt;",
63-
'&' => "&amp;",
64-
_ => continue,
65-
};
66-
fmt.write_str(&pile_o_bits[last..i])?;
67-
fmt.write_str(s)?;
68-
// NOTE: we only expect single byte characters here - which is fine as long as we
69-
// only match single byte characters
70-
last = i + 1;
71-
}
72-
73-
if last < s.len() {
74-
fmt.write_str(&pile_o_bits[last..])?;
75-
}
76-
Ok(())
58+
escape(self.0, fmt, false)
7759
}
7860
}
7961

0 commit comments

Comments
 (0)