vy_core/
escape.rs

1use alloc::string::String;
2
3use crate::{buffer::Buffer, IntoHtml};
4
5#[inline]
6pub const fn escape_char(ch: char) -> Option<&'static str> {
7    match ch {
8        '&' => Some("&amp;"),
9        '<' => Some("&lt;"),
10        '>' => Some("&gt;"),
11        '"' => Some("&quot;"),
12        _ => None,
13    }
14}
15
16/// Escapes all special HTML characters in `input` and writes the result into
17/// `buf`.
18#[inline]
19pub fn escape_into(output: &mut Buffer, input: &str) {
20    for ch in input.chars() {
21        match escape_char(ch) {
22            Some(esc) => output.push_str(esc),
23            _ => output.push(ch),
24        };
25    }
26}
27
28/// Escapes all special HTML characters in `input`.
29#[inline]
30pub fn escape(input: &str) -> Buffer {
31    let mut output = Buffer::with_capacity(input.len());
32    escape_into(&mut output, input);
33    output
34}
35
36/// A type that requires no further escaping.
37pub struct PreEscaped<T>(pub T);
38
39impl IntoHtml for PreEscaped<&str> {
40    #[inline]
41    fn into_html(self) -> impl IntoHtml {
42        self
43    }
44
45    #[inline]
46    fn escape_and_write(self, buf: &mut Buffer) {
47        buf.push_str(self.0);
48    }
49
50    #[inline]
51    fn size_hint(&self) -> usize {
52        self.0.len()
53    }
54}
55
56impl IntoHtml for PreEscaped<String> {
57    #[inline]
58    fn into_html(self) -> impl IntoHtml {
59        self
60    }
61
62    #[inline]
63    fn escape_and_write(self, buf: &mut Buffer) {
64        buf.push_str(&self.0);
65    }
66}
67
68impl IntoHtml for PreEscaped<char> {
69    #[inline]
70    fn into_html(self) -> impl IntoHtml {
71        self
72    }
73
74    #[inline]
75    fn escape_and_write(self, buf: &mut Buffer) {
76        buf.push(self.0);
77    }
78
79    #[inline]
80    fn size_hint(&self) -> usize {
81        self.0.len_utf8()
82    }
83}