html_escape/encode/html_entity/
unquoted_attribute.rs1use alloc::{borrow::Cow, string::String, vec::Vec};
2use core::str::from_utf8_unchecked;
3#[cfg(feature = "std")]
4use std::io::{self, Write};
5
6use crate::functions::*;
7
8pub fn encode_unquoted_attribute<S: ?Sized + AsRef<str>>(text: &S) -> Cow<'_, str> {
19 let text = text.as_ref();
20 let text_bytes = text.as_bytes();
21
22 let text_length = text_bytes.len();
23
24 let mut p = 0;
25 let mut e;
26
27 loop {
28 if p == text_length {
29 return Cow::from(text);
30 }
31
32 e = text_bytes[p];
33
34 if e.is_ascii() && !e.is_ascii_alphanumeric() {
35 break;
36 }
37
38 p += 1;
39 }
40
41 let mut v = Vec::with_capacity(text_length);
42
43 v.extend_from_slice(&text_bytes[..p]);
44
45 write_html_entity_to_vec(e, &mut v);
46
47 encode_unquoted_attribute_to_vec(
48 unsafe { from_utf8_unchecked(&text_bytes[(p + 1)..]) },
49 &mut v,
50 );
51
52 Cow::from(unsafe { String::from_utf8_unchecked(v) })
53}
54
55#[inline]
66pub fn encode_unquoted_attribute_to_string<S: AsRef<str>>(text: S, output: &mut String) -> &str {
67 unsafe { from_utf8_unchecked(encode_unquoted_attribute_to_vec(text, output.as_mut_vec())) }
68}
69
70pub fn encode_unquoted_attribute_to_vec<S: AsRef<str>>(text: S, output: &mut Vec<u8>) -> &[u8] {
81 let text = text.as_ref();
82 let text_bytes = text.as_bytes();
83 let text_length = text_bytes.len();
84
85 output.reserve(text_length);
86
87 let current_length = output.len();
88
89 let mut p = 0;
90 let mut e;
91
92 let mut start = 0;
93
94 while p < text_length {
95 e = text_bytes[p];
96
97 if e.is_ascii() && !e.is_ascii_alphanumeric() {
98 output.extend_from_slice(&text_bytes[start..p]);
99 start = p + 1;
100 write_html_entity_to_vec(e, output);
101 }
102
103 p += 1;
104 }
105
106 output.extend_from_slice(&text_bytes[start..p]);
107
108 &output[current_length..]
109}
110
111#[cfg(feature = "std")]
112pub fn encode_unquoted_attribute_to_writer<S: AsRef<str>, W: Write>(
123 text: S,
124 output: &mut W,
125) -> Result<(), io::Error> {
126 let text = text.as_ref();
127 let text_bytes = text.as_bytes();
128 let text_length = text_bytes.len();
129
130 let mut p = 0;
131 let mut e;
132
133 let mut start = 0;
134
135 while p < text_length {
136 e = text_bytes[p];
137
138 if e.is_ascii() && !e.is_ascii_alphanumeric() {
139 output.write_all(&text_bytes[start..p])?;
140 start = p + 1;
141 write_html_entity_to_writer(e, output)?;
142 }
143
144 p += 1;
145 }
146
147 output.write_all(&text_bytes[start..p])
148}