From 884382bac4becd722d105bb52d3e31790f7ebe04 Mon Sep 17 00:00:00 2001 From: pwygab <88221256+merelymyself@users.noreply.github.com> Date: Tue, 23 Aug 2022 19:51:07 +0800 Subject: [PATCH] preserve space by letting `to nuon` only add quotes when necessary (#6379) * preserve space by letting `to nuon` only add quotes when necessary * fix CI, add quotes with colon * fmt * add more chars to blacklist --- crates/nu-command/src/formats/to/nuon.rs | 49 +++++++++++++++++-- .../tests/format_conversions/nuon.rs | 18 +++++++ 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/crates/nu-command/src/formats/to/nuon.rs b/crates/nu-command/src/formats/to/nuon.rs index 7d0cf5bc2..e2eb39176 100644 --- a/crates/nu-command/src/formats/to/nuon.rs +++ b/crates/nu-command/src/formats/to/nuon.rs @@ -104,7 +104,13 @@ fn value_to_string(v: &Value, span: Span) -> Result { // Table output let headers: Vec = headers .iter() - .map(|string| format!("\"{}\"", string)) + .map(|string| { + if needs_quotes(string) { + format!("\"{}\"", string) + } else { + string.to_string() + } + }) .collect(); let headers_output = headers.join(", "); @@ -114,7 +120,7 @@ fn value_to_string(v: &Value, span: Span) -> Result { if let Value::Record { vals, .. } = val { for val in vals { - row.push(value_to_string(val, span)?); + row.push(value_to_string_without_quotes(val, span)?); } } @@ -129,7 +135,7 @@ fn value_to_string(v: &Value, span: Span) -> Result { } else { let mut collection = vec![]; for val in vals { - collection.push(value_to_string(val, span)?); + collection.push(value_to_string_without_quotes(val, span)?); } Ok(format!("[{}]", collection.join(", "))) } @@ -148,7 +154,15 @@ fn value_to_string(v: &Value, span: Span) -> Result { Value::Record { cols, vals, .. } => { let mut collection = vec![]; for (col, val) in cols.iter().zip(vals) { - collection.push(format!("\"{}\": {}", col, value_to_string(val, span)?)); + collection.push(if needs_quotes(col) { + format!( + "\"{}\": {}", + col, + value_to_string_without_quotes(val, span)? + ) + } else { + format!("{}: {}", col, value_to_string_without_quotes(val, span)?) + }); } Ok(format!("{{{}}}", collection.join(", "))) } @@ -156,12 +170,39 @@ fn value_to_string(v: &Value, span: Span) -> Result { } } +fn value_to_string_without_quotes(v: &Value, span: Span) -> Result { + match v { + Value::String { val, .. } => Ok({ + let mut quoted = escape_quote_string(val); + if !needs_quotes(val) { + quoted.remove(0); + quoted.pop(); + } + quoted + }), + _ => value_to_string(v, span), + } +} + fn to_nuon(call: &Call, input: PipelineData) -> Result { let v = input.into_value(call.head); value_to_string(&v, call.head) } +fn needs_quotes(string: &str) -> bool { + string.contains(' ') + || string.contains(',') + || string.contains(':') + || string.contains(';') + || string.contains('(') + || string.contains(')') + || string.contains('[') + || string.contains(']') + || string.contains('{') + || string.contains('}') +} + #[cfg(test)] mod test { #[test] diff --git a/crates/nu-command/tests/format_conversions/nuon.rs b/crates/nu-command/tests/format_conversions/nuon.rs index d98751323..626cb05bf 100644 --- a/crates/nu-command/tests/format_conversions/nuon.rs +++ b/crates/nu-command/tests/format_conversions/nuon.rs @@ -249,3 +249,21 @@ fn to_nuon_converts_columns_with_spaces() { )); assert!(actual.err.is_empty()); } + +#[test] +fn to_nuon_does_not_quote_unnecessarily() { + let actual = nu!( + cwd: "tests/fixtures/formats", pipeline( + r#" + let test = [["a", "b", "c d"]; [1 2 3] [4 5 6]]; $test | to nuon + "# + )); + assert_eq!(actual.out, "[[a, b, \"c d\"]; [1, 2, 3], [4, 5, 6]]"); + let actual = nu!( + cwd: "tests/fixtures/formats", pipeline( + r#" + let a = {"ro name": "sam" rank: 10}; $a | to nuon + "# + )); + assert_eq!(actual.out, "{\"ro name\": sam, rank: 10}"); +}