git.delta.rocks / jrsonnet / refs/commits / 3fbc4663764a

difftreelog

perf do not allocate on every string conversion

Yaroslav Bolyukin2021-07-10parent: #a5cec24.patch.diff
in: master

1 file changed

modifiedcrates/jrsonnet-evaluator/src/builtin/manifest.rsdiffbeforeafterboth
42 }42 }
43 }43 }
44 Val::Null => buf.push_str("null"),44 Val::Null => buf.push_str("null"),
45 Val::Str(s) => buf.push_str(&escape_string_json(s)),45 Val::Str(s) => escape_string_json_buf(s, buf),
46 Val::Num(n) => write!(buf, "{}", n).unwrap(),46 Val::Num(n) => write!(buf, "{}", n).unwrap(),
47 Val::Arr(items) => {47 Val::Arr(items) => {
48 buf.push('[');48 buf.push('[');
100 }100 }
101 }101 }
102 buf.push_str(cur_padding);102 buf.push_str(cur_padding);
103 buf.push_str(&escape_string_json(&field));103 escape_string_json_buf(&field, &mut buf);
104 buf.push_str(": ");104 buf.push_str(": ");
105 crate::push(105 crate::push(
106 None,106 None,
130 Ok(())130 Ok(())
131}131}
132
132pub fn escape_string_json(s: &str) -> String {133pub fn manifest_string_json(s: &str) -> String {
134 let mut buf = String::new();
135 escape_string_json_buf(s, &mut buf);
136 buf
137}
138
139fn escape_string_json_buf(s: &str, buf: &mut String) {
133 use std::fmt::Write;140 use std::fmt::Write;
134 let mut out = String::new();
135 out.push('"');141 buf.push('"');
136 for c in s.chars() {142 for c in s.chars() {
137 match c {143 match c {
138 '"' => out.push_str("\\\""),144 '"' => buf.push_str("\\\""),
139 '\\' => out.push_str("\\\\"),145 '\\' => buf.push_str("\\\\"),
140 '\u{0008}' => out.push_str("\\b"),146 '\u{0008}' => buf.push_str("\\b"),
141 '\u{000c}' => out.push_str("\\f"),147 '\u{000c}' => buf.push_str("\\f"),
142 '\n' => out.push_str("\\n"),148 '\n' => buf.push_str("\\n"),
143 '\r' => out.push_str("\\r"),149 '\r' => buf.push_str("\\r"),
144 '\t' => out.push_str("\\t"),150 '\t' => buf.push_str("\\t"),
145 c if c < 32 as char || (c >= 127 as char && c <= 159 as char) => {151 c if c < 32 as char || (c >= 127 as char && c <= 159 as char) => {
146 write!(out, "\\u{:04x}", c as u32).unwrap()152 write!(buf, "\\u{:04x}", c as u32).unwrap()
147 }153 }
148 c => out.push(c),154 c => buf.push(c),
149 }155 }
150 }156 }
151 out.push('"');157 buf.push('"');
152 out
153}158}
154
155#[test]
156fn json_test() {
157 assert_eq!(escape_string_json("\u{001f}"), "\"\\u001f\"")
158}
159159