1#[inline]
2pub fn escape_generic<S: AsRef<str>>(s: S) -> String {
7 let s = s.as_ref();
8 let bytes = s.as_bytes();
9
10 let estimated_capacity = bytes.len() + bytes.len() / 2 + 2;
13 let mut result = Vec::with_capacity(estimated_capacity);
14
15 result.push(b'"');
16
17 let mut start = 0;
18 let mut i = 0;
19
20 while i < bytes.len() {
21 let b = bytes[i];
22
23 let escape_byte = ESCAPE[b as usize];
25
26 if escape_byte == 0 {
27 i += 1;
29 continue;
30 }
31
32 if start < i {
34 result.extend_from_slice(&bytes[start..i]);
35 }
36
37 result.push(b'\\');
39 if escape_byte == b'u' {
40 result.extend_from_slice(b"u00");
42 let hex_digits = &HEX_BYTES[b as usize];
43 result.push(hex_digits.0);
44 result.push(hex_digits.1);
45 } else {
46 result.push(escape_byte);
48 }
49
50 i += 1;
51 start = i;
52 }
53
54 if start < bytes.len() {
56 result.extend_from_slice(&bytes[start..]);
57 }
58
59 result.push(b'"');
60
61 unsafe { String::from_utf8_unchecked(result) }
63}
64
65const BB: u8 = b'b'; const TT: u8 = b't'; const NN: u8 = b'n'; const FF: u8 = b'f'; const RR: u8 = b'r'; const QU: u8 = b'"'; const BS: u8 = b'\\'; pub(crate) const UU: u8 = b'u'; const __: u8 = 0;
74
75pub(crate) static ESCAPE: [u8; 256] = [
78 UU, UU, UU, UU, UU, UU, UU, UU, BB, TT, NN, UU, FF, RR, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, __, __, QU, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, BS, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, ];
96
97pub(crate) struct HexPair(u8, u8);
99
100pub(crate) static HEX_BYTES: [HexPair; 32] = [
101 HexPair(b'0', b'0'),
102 HexPair(b'0', b'1'),
103 HexPair(b'0', b'2'),
104 HexPair(b'0', b'3'),
105 HexPair(b'0', b'4'),
106 HexPair(b'0', b'5'),
107 HexPair(b'0', b'6'),
108 HexPair(b'0', b'7'),
109 HexPair(b'0', b'8'),
110 HexPair(b'0', b'9'),
111 HexPair(b'0', b'a'),
112 HexPair(b'0', b'b'),
113 HexPair(b'0', b'c'),
114 HexPair(b'0', b'd'),
115 HexPair(b'0', b'e'),
116 HexPair(b'0', b'f'),
117 HexPair(b'1', b'0'),
118 HexPair(b'1', b'1'),
119 HexPair(b'1', b'2'),
120 HexPair(b'1', b'3'),
121 HexPair(b'1', b'4'),
122 HexPair(b'1', b'5'),
123 HexPair(b'1', b'6'),
124 HexPair(b'1', b'7'),
125 HexPair(b'1', b'8'),
126 HexPair(b'1', b'9'),
127 HexPair(b'1', b'a'),
128 HexPair(b'1', b'b'),
129 HexPair(b'1', b'c'),
130 HexPair(b'1', b'd'),
131 HexPair(b'1', b'e'),
132 HexPair(b'1', b'f'),
133];