git.delta.rocks / jrsonnet / refs/commits / b118a83916a3

difftreelog

feat quote_keys option for Yaml

Yaroslav Bolyukin2021-11-27parent: #df9bc99.patch.diff
in: master

5 files changed

modifiedCargo.lockdiffbeforeafterboth
114 "bitflags",114 "bitflags",
115]115]
116
117[[package]]
118name = "dtoa"
119version = "0.4.8"
120source = "registry+https://github.com/rust-lang/crates.io-index"
121checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0"
116122
117[[package]]123[[package]]
118name = "gcmodule"124name = "gcmodule"
216 "rustc-hash",222 "rustc-hash",
217 "serde",223 "serde",
218 "serde_json",224 "serde_json",
225 "serde_yaml",
219 "thiserror",226 "thiserror",
220]227]
221228
272source = "registry+https://github.com/rust-lang/crates.io-index"279source = "registry+https://github.com/rust-lang/crates.io-index"
273checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119"280checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119"
281
282[[package]]
283name = "linked-hash-map"
284version = "0.5.4"
285source = "registry+https://github.com/rust-lang/crates.io-index"
286checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
274287
275[[package]]288[[package]]
276name = "lock_api"289name = "lock_api"
466 "serde",479 "serde",
467]480]
481
482[[package]]
483name = "serde_yaml"
484version = "0.8.21"
485source = "git+https://github.com/CertainLach/serde-yaml?branch=feature/old-octals-quirk#4bf0e325243539fdeb419e8d727ed1c161cbe445"
486dependencies = [
487 "dtoa",
488 "indexmap",
489 "serde",
490 "yaml-rust",
491]
468492
469[[package]]493[[package]]
470name = "smallvec"494name = "smallvec"
600source = "registry+https://github.com/rust-lang/crates.io-index"624source = "registry+https://github.com/rust-lang/crates.io-index"
601checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"625checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
626
627[[package]]
628name = "yaml-rust"
629version = "0.4.5"
630source = "registry+https://github.com/rust-lang/crates.io-index"
631checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
632dependencies = [
633 "linked-hash-map",
634]
602635
603[[package]]636[[package]]
604name = "yansi-term"637name = "yansi-term"
modifiedcrates/jrsonnet-evaluator/src/builtin/manifest.rsdiffbeforeafterboth
173 /// ## <- this173 /// ## <- this
174 /// ```174 /// ```
175 pub arr_element_padding: &'s str,175 pub arr_element_padding: &'s str,
176 /// Should yaml keys appear unescaped, when possible
177 /// ```yaml
178 /// "safe_key": 1
179 /// # vs
180 /// safe_key: 1
181 /// ```
182 pub quote_keys: bool,
176}183}
184
185/// From https://github.com/chyh1990/yaml-rust/blob/da52a68615f2ecdd6b7e4567019f280c433c1521/src/emitter.rs#L289
186/// With added date check
187fn yaml_needs_quotes(string: &str) -> bool {
188 fn need_quotes_spaces(string: &str) -> bool {
189 string.starts_with(' ') || string.ends_with(' ')
190 }
191
192 string == ""
193 || need_quotes_spaces(string)
194 || string.starts_with(|character: char| match character {
195 '&' | '*' | '?' | '|' | '-' | '<' | '>' | '=' | '!' | '%' | '@' => true,
196 _ => false,
197 }) || string.contains(|character: char| match character {
198 ':'
199 | '{'
200 | '}'
201 | '['
202 | ']'
203 | ','
204 | '#'
205 | '`'
206 | '\"'
207 | '\''
208 | '\\'
209 | '\0'..='\x06'
210 | '\t'
211 | '\n'
212 | '\r'
213 | '\x0e'..='\x1a'
214 | '\x1c'..='\x1f' => true,
215 _ => false,
216 }) || [
217 // http://yaml.org/type/bool.html
218 // Note: 'y', 'Y', 'n', 'N', is not quoted deliberately, as in libyaml. PyYAML also parse
219 // them as string, not booleans, although it is violating the YAML 1.1 specification.
220 // See https://github.com/dtolnay/serde-yaml/pull/83#discussion_r152628088.
221 "yes", "Yes", "YES", "no", "No", "NO", "True", "TRUE", "true", "False", "FALSE", "false",
222 "on", "On", "ON", "off", "Off", "OFF", // http://yaml.org/type/null.html
223 "null", "Null", "NULL", "~",
224 ]
225 .contains(&string)
226 || (string.chars().all(|c| matches!(c, '0'..='9' | '-'))
227 && string.chars().filter(|c| *c == '-').count() == 2)
228 || string.starts_with('.')
229 || string.starts_with("0x")
230 || string.parse::<i64>().is_ok()
231 || string.parse::<f64>().is_ok()
232}
177233
178pub fn manifest_yaml_ex(val: &Val, options: &ManifestYamlOptions<'_>) -> Result<String> {234pub fn manifest_yaml_ex(val: &Val, options: &ManifestYamlOptions<'_>) -> Result<String> {
179 let mut out = String::new();235 let mut out = String::new();
206 buf.push_str(options.padding);262 buf.push_str(options.padding);
207 buf.push_str(line);263 buf.push_str(line);
208 }264 }
209 } else {265 } else if !options.quote_keys && !yaml_needs_quotes(&s) {
266 buf.push_str(&s);
267 } else {
210 escape_string_json_buf(s, buf)268 escape_string_json_buf(s, buf);
211 }269 }
212 }270 }
213 Val::Num(n) => write!(buf, "{}", *n).unwrap(),271 Val::Num(n) => write!(buf, "{}", *n).unwrap(),
253 buf.push('\n');311 buf.push('\n');
254 buf.push_str(cur_padding);312 buf.push_str(cur_padding);
255 }313 }
314 if !options.quote_keys && !yaml_needs_quotes(&key) {
315 buf.push_str(&key);
316 } else {
256 escape_string_json_buf(key, buf);317 escape_string_json_buf(key, buf);
318 }
257 buf.push(':');319 buf.push(':');
258 let prev_len = cur_padding.len();320 let prev_len = cur_padding.len();
259 let item = o.get(key.clone())?.expect("field exists");321 let item = o.get(key.clone())?.expect("field exists");
modifiedcrates/jrsonnet-evaluator/src/builtin/mod.rsdiffbeforeafterboth
753 _loc: &ExprLocation,753 _loc: &ExprLocation,
754 args: &ArgsDesc,754 args: &ArgsDesc,
755) -> Result<Val> {755) -> Result<Val> {
756 parse_args!(context, "manifestYamlDoc", args, 2, [756 parse_args!(context, "manifestYamlDoc", args, 3, [
757 0, value: ty!(any);757 0, value: ty!(any);
758 1, indent_array_in_object: ty!(boolean) => Val::Bool;758 1, indent_array_in_object: ty!(boolean) => Val::Bool;
759 2, quote_keys: ty!(boolean) => Val::Bool;
759 ], {760 ], {
760 Ok(Val::Str(manifest_yaml_ex(&value, &ManifestYamlOptions {761 Ok(Val::Str(manifest_yaml_ex(&value, &ManifestYamlOptions {
761 padding: " ",762 padding: " ",
762 arr_element_padding: if indent_array_in_object { " " } else { "" },763 arr_element_padding: if indent_array_in_object { " " } else { "" },
764 quote_keys,
763 })?.into()))765 })?.into()))
764 })766 })
765}767}
modifiedcrates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth
556 &ManifestYamlOptions {556 &ManifestYamlOptions {
557 padding,557 padding,
558 arr_element_padding: padding,558 arr_element_padding: padding,
559 quote_keys: false,
559 },560 },
560 )561 )
561 .map(|s| s.into())562 .map(|s| s.into())
modifiedcrates/jrsonnet-stdlib/src/std.jsonnetdiffbeforeafterboth
377377
378 manifestYamlDocImpl:: $intrinsic(manifestYamlDocImpl),378 manifestYamlDocImpl:: $intrinsic(manifestYamlDocImpl),
379379
380 manifestYamlDoc(value, indent_array_in_object=false):: std.manifestYamlDocImpl(value, indent_array_in_object),380 manifestYamlDoc(value, indent_array_in_object=false, quote_keys=true):: std.manifestYamlDocImpl(value, indent_array_in_object, quote_keys),
381381
382 manifestYamlStream(value, indent_array_in_object=false, c_document_end=true)::382 manifestYamlStream(value, indent_array_in_object=false, c_document_end=true)::
383 if !std.isArray(value) then383 if !std.isArray(value) then