diff options
Diffstat (limited to 'src/librustdoc/html/escape.rs')
-rw-r--r-- | src/librustdoc/html/escape.rs | 40 |
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 { + '>' => ">", + '<' => "<", + '&' => "&", + '\'' => "'", + '"' => """, + _ => 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(()) + } +} |