|
1 | 1 | use std::convert::Infallible;
|
2 | 2 | use std::fmt::{self, Display, Formatter, Write};
|
3 |
| -use std::num::NonZeroU8; |
4 | 3 | use std::{borrow, str};
|
5 | 4 |
|
6 | 5 | /// Marks a string (or other `Display` type) as safe
|
@@ -83,69 +82,14 @@ pub fn e(text: impl fmt::Display, escaper: impl Escaper) -> Result<Safe<impl Dis
|
83 | 82 | pub struct Html;
|
84 | 83 |
|
85 | 84 | impl Escaper for Html {
|
86 |
| - fn write_escaped_str<W: Write>(&self, mut fmt: W, string: &str) -> fmt::Result { |
87 |
| - let mut escaped_buf = *b"&#__;"; |
88 |
| - let mut last = 0; |
89 |
| - |
90 |
| - for (index, byte) in string.bytes().enumerate() { |
91 |
| - const MIN_CHAR: u8 = b'"'; |
92 |
| - const MAX_CHAR: u8 = b'>'; |
93 |
| - |
94 |
| - struct Table { |
95 |
| - _align: [usize; 0], |
96 |
| - lookup: [Option<[NonZeroU8; 2]>; (MAX_CHAR - MIN_CHAR + 1) as usize], |
97 |
| - } |
98 |
| - |
99 |
| - const TABLE: Table = { |
100 |
| - const fn n(c: u8) -> Option<[NonZeroU8; 2]> { |
101 |
| - let n0 = match NonZeroU8::new(c / 10 + b'0') { |
102 |
| - Some(n) => n, |
103 |
| - None => panic!(), |
104 |
| - }; |
105 |
| - let n1 = match NonZeroU8::new(c % 10 + b'0') { |
106 |
| - Some(n) => n, |
107 |
| - None => panic!(), |
108 |
| - }; |
109 |
| - Some([n0, n1]) |
110 |
| - } |
111 |
| - |
112 |
| - let mut table = Table { |
113 |
| - _align: [], |
114 |
| - lookup: [None; (MAX_CHAR - MIN_CHAR + 1) as usize], |
115 |
| - }; |
116 |
| - |
117 |
| - table.lookup[(b'"' - MIN_CHAR) as usize] = n(b'"'); |
118 |
| - table.lookup[(b'&' - MIN_CHAR) as usize] = n(b'&'); |
119 |
| - table.lookup[(b'\'' - MIN_CHAR) as usize] = n(b'\''); |
120 |
| - table.lookup[(b'<' - MIN_CHAR) as usize] = n(b'<'); |
121 |
| - table.lookup[(b'>' - MIN_CHAR) as usize] = n(b'>'); |
122 |
| - table |
123 |
| - }; |
124 |
| - |
125 |
| - let escaped = match byte { |
126 |
| - MIN_CHAR..=MAX_CHAR => TABLE.lookup[(byte - MIN_CHAR) as usize], |
127 |
| - _ => None, |
128 |
| - }; |
129 |
| - if let Some(escaped) = escaped { |
130 |
| - escaped_buf[2] = escaped[0].get(); |
131 |
| - escaped_buf[3] = escaped[1].get(); |
132 |
| - fmt.write_str(&string[last..index])?; |
133 |
| - fmt.write_str(unsafe { std::str::from_utf8_unchecked(escaped_buf.as_slice()) })?; |
134 |
| - last = index + 1; |
135 |
| - } |
136 |
| - } |
137 |
| - fmt.write_str(&string[last..]) |
| 85 | + #[inline] |
| 86 | + fn write_escaped_str<W: Write>(&self, fmt: W, string: &str) -> fmt::Result { |
| 87 | + crate::html::write_escaped_str(fmt, string) |
138 | 88 | }
|
139 | 89 |
|
140 |
| - fn write_escaped_char<W: Write>(&self, mut fmt: W, c: char) -> fmt::Result { |
141 |
| - fmt.write_str(match (c.is_ascii(), c as u8) { |
142 |
| - (true, b'"') => """, |
143 |
| - (true, b'&') => "&", |
144 |
| - (true, b'\'') => "'", |
145 |
| - (true, b'<') => "<", |
146 |
| - (true, b'>') => ">", |
147 |
| - _ => return fmt.write_char(c), |
148 |
| - }) |
| 90 | + #[inline] |
| 91 | + fn write_escaped_char<W: Write>(&self, fmt: W, c: char) -> fmt::Result { |
| 92 | + crate::html::write_escaped_char(fmt, c) |
149 | 93 | }
|
150 | 94 | }
|
151 | 95 |
|
|
0 commit comments