git.delta.rocks / jrsonnet / refs/commits / 2b4e36fe5944

difftreelog

perf adopt string escape code from serde-json

Yaroslav Bolyukin2022-11-10parent: #a7e4b59.patch.diff
in: master

1 file changed

modifiedcrates/jrsonnet-evaluator/src/stdlib/manifest.rsdiffbeforeafterboth
259 buf259 buf
260}260}
261
262// Json string encoding was borrowed from https://github.com/serde-rs/json
263
264const BB: u8 = b'b'; // \x08
265const TT: u8 = b't'; // \x09
266const NN: u8 = b'n'; // \x0A
267const FF: u8 = b'f'; // \x0C
268const RR: u8 = b'r'; // \x0D
269const QU: u8 = b'"'; // \x22
270const BS: u8 = b'\\'; // \x5C
271const UU: u8 = b'u'; // \x00...\x1F except the ones above
272const __: u8 = 0;
273
274// Lookup table of escape sequences. A value of b'x' at index i means that byte
275// i is escaped as "\x" in JSON. A value of 0 means that byte i is not escaped.
276static ESCAPE: [u8; 256] = [
277 // 1 2 3 4 5 6 7 8 9 A B C D E F
278 UU, UU, UU, UU, UU, UU, UU, UU, BB, TT, NN, UU, FF, RR, UU, UU, // 0
279 UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, // 1
280 __, __, QU, __, __, __, __, __, __, __, __, __, __, __, __, __, // 2
281 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 3
282 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 4
283 __, __, __, __, __, __, __, __, __, __, __, __, BS, __, __, __, // 5
284 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 6
285 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 7
286 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 8
287 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 9
288 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // A
289 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // B
290 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // C
291 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // D
292 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // E
293 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // F
294];
261295
262fn escape_string_json_buf(s: &str, buf: &mut String) {296fn escape_string_json_buf(value: &str, buf: &mut String) {
297 // Safety: we only write correct utf-8 in this function
263 buf.push('"');298 let mut buf: &mut Vec<u8> = unsafe { core::mem::transmute(buf) };
264 for c in s.chars() {299 let bytes = value.as_bytes();
265 match c {300
266 '"' => buf.push_str("\\\""),301 // Perfect for ascii strings, removes any reallocations
302 buf.reserve(value.len() + 2);
303
267 '\\' => buf.push_str("\\\\"),304 buf.push(b'"');
305
306 let mut start = 0;
307
268 '\u{0008}' => buf.push_str("\\b"),308 for (i, &byte) in bytes.iter().enumerate() {
269 '\u{000c}' => buf.push_str("\\f"),309 let escape = ESCAPE[byte as usize];
310 if escape == __ {
311 continue;
312 }
313
314 if start < i {
270 '\n' => buf.push_str("\\n"),315 buf.extend_from_slice(&bytes[start..i]);
271 '\r' => buf.push_str("\\r"),316 }
317 start = i + 1;
318
319 match escape {
272 '\t' => buf.push_str("\\t"),320 self::BB | self::TT | self::NN | self::FF | self::RR | self::QU | self::BS => {
321 buf.extend_from_slice(&[b'\\', escape])
322 }
323 self::UU => {
324 static HEX_DIGITS: [u8; 16] = *b"0123456789abcdef";
325 let bytes = &[
326 b'\\',
327 b'u',
328 b'0',
329 b'0',
273 c if c < 32 as char || (c >= 127 as char && c <= 159 as char) => {330 HEX_DIGITS[(byte >> 4) as usize],
331 HEX_DIGITS[(byte & 0xF) as usize],
332 ];
274 write!(buf, "\\u{:04x}", c as u32).unwrap();333 buf.extend_from_slice(bytes)
275 }334 }
276 c => buf.push(c),335 _ => unreachable!(),
277 }336 }
278 }337 }
338
339 if start == bytes.len() {
340 buf.push(b'"');
341 return;
342 }
343
344 buf.extend_from_slice(&bytes[start..]);
279 buf.push('"');345 buf.push(b'"');
280}346}
281347
282pub struct YamlFormat<'s> {348pub struct YamlFormat<'s> {