summaryrefslogtreecommitdiffstats
path: root/src/librustdoc/html/escape.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/librustdoc/html/escape.rs')
-rw-r--r--src/librustdoc/html/escape.rs40
1 files changed, 40 insertions, 0 deletions
diff --git a/src/librustdoc/html/escape.rs b/src/librustdoc/html/escape.rs
new file mode 100644
index 000000000..4a19d0a44
--- /dev/null
+++ b/src/librustdoc/html/escape.rs
@@ -0,0 +1,40 @@
+//! HTML escaping.
+//!
+//! This module contains one unit struct, which can be used to HTML-escape a
+//! string of text (for use in a format string).
+
+use std::fmt;
+
+/// Wrapper struct which will emit the HTML-escaped version of the contained
+/// string when passed to a format string.
+pub(crate) struct Escape<'a>(pub &'a str);
+
+impl<'a> fmt::Display for Escape<'a> {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ // Because the internet is always right, turns out there's not that many
+ // characters to escape: http://stackoverflow.com/questions/7381974
+ let Escape(s) = *self;
+ let pile_o_bits = s;
+ let mut last = 0;
+ for (i, ch) in s.char_indices() {
+ let s = match ch {
+ '>' => "&gt;",
+ '<' => "&lt;",
+ '&' => "&amp;",
+ '\'' => "&#39;",
+ '"' => "&quot;",
+ _ => continue,
+ };
+ fmt.write_str(&pile_o_bits[last..i])?;
+ fmt.write_str(s)?;
+ // NOTE: we only expect single byte characters here - which is fine as long as we
+ // only match single byte characters
+ last = i + 1;
+ }
+
+ if last < s.len() {
+ fmt.write_str(&pile_o_bits[last..])?;
+ }
+ Ok(())
+ }
+}