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