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("&"),
9 '<' => Some("<"),
10 '>' => Some(">"),
11 '"' => Some("""),
12 _ => None,
13 }
14}
15
16#[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#[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
36pub 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}