1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#![cfg_attr(not(test), no_std)]

//! Internal support code used by the [Maud] template engine.
//!
//! You should not need to depend on this crate directly.
//!
//! [Maud]: https://maud.lambda.xyz

#![doc(html_root_url = "https://docs.rs/maud_htmlescape/0.17.1")]

extern crate alloc;

use alloc::string::String;
use core::fmt;

/// An adapter that escapes HTML special characters.
///
/// The following characters are escaped:
///
/// * `&` is escaped as `&`
/// * `<` is escaped as `&lt;`
/// * `>` is escaped as `&gt;`
/// * `"` is escaped as `&quot;`
///
/// All other characters are passed through unchanged.
///
/// **Note:** In versions prior to 0.13, the single quote (`'`) was
/// escaped as well.
///
/// # Example
///
/// ```rust,ignore
/// use std::fmt::Write;
/// let mut s = String::new();
/// write!(Escaper::new(&mut s), "<script>launchMissiles()</script>").unwrap();
/// assert_eq!(s, "&lt;script&gt;launchMissiles()&lt;/script&gt;");
/// ```
pub struct Escaper<'a>(&'a mut String);

impl<'a> Escaper<'a> {
    /// Creates an `Escaper` from a `String`.
    pub fn new(buffer: &'a mut String) -> Escaper<'a> {
        Escaper(buffer)
    }
}

impl<'a> fmt::Write for Escaper<'a> {
    fn write_str(&mut self, s: &str) -> fmt::Result {
        for b in s.bytes() {
            match b {
                b'&' => self.0.push_str("&amp;"),
                b'<' => self.0.push_str("&lt;"),
                b'>' => self.0.push_str("&gt;"),
                b'"' => self.0.push_str("&quot;"),
                _ => unsafe { self.0.as_mut_vec().push(b) },
            }
        }
        Ok(())
    }
}

#[cfg(test)]
mod test {
    use crate::Escaper;
    use std::fmt::Write;

    #[test]
    fn it_works() {
        let mut s = String::new();
        write!(Escaper::new(&mut s), "<script>launchMissiles()</script>").unwrap();
        assert_eq!(s, "&lt;script&gt;launchMissiles()&lt;/script&gt;");
    }
}