From 5d3b63fa90fb9615bf7e01ef4451bf745f0aadfa Mon Sep 17 00:00:00 2001 From: Michael Angerman Date: Wed, 22 Dec 2021 11:56:49 -0800 Subject: [PATCH] add in a raw flag in the command to json (#555) * add in the method to_string_raw * add in a raw flag to json * add in a test --- crates/nu-command/src/formats/to/json.rs | 30 ++++++++++++++++++++++-- crates/nu-json/src/lib.rs | 2 +- crates/nu-json/src/ser.rs | 13 ++++++++++ src/tests.rs | 8 +++++++ 4 files changed, 50 insertions(+), 3 deletions(-) diff --git a/crates/nu-command/src/formats/to/json.rs b/crates/nu-command/src/formats/to/json.rs index 8e35048b5a..fcf94ef214 100644 --- a/crates/nu-command/src/formats/to/json.rs +++ b/crates/nu-command/src/formats/to/json.rs @@ -13,7 +13,9 @@ impl Command for ToJson { } fn signature(&self) -> Signature { - Signature::build("to json").category(Category::Formats) + Signature::build("to json") + .switch("raw", "remove all of the whitespace", Some('r')) + .category(Category::Formats) } fn usage(&self) -> &str { @@ -27,7 +29,12 @@ impl Command for ToJson { call: &Call, input: PipelineData, ) -> Result { - to_json(call, input) + let raw = call.has_flag("raw"); + if raw { + to_json_raw(call, input) + } else { + to_json(call, input) + } } fn examples(&self) -> Vec { @@ -106,6 +113,25 @@ fn to_json(call: &Call, input: PipelineData) -> Result } } +fn to_json_raw(call: &Call, input: PipelineData) -> Result { + let span = call.head; + + let value = input.into_value(span); + + let json_value = value_to_json_value(&value)?; + match nu_json::to_string_raw(&json_value) { + Ok(serde_json_string) => Ok(Value::String { + val: serde_json_string, + span, + } + .into_pipeline_data()), + _ => Ok(Value::Error { + error: ShellError::CantConvert("JSON".into(), value.get_type().to_string(), span), + } + .into_pipeline_data()), + } +} + #[cfg(test)] mod test { use super::*; diff --git a/crates/nu-json/src/lib.rs b/crates/nu-json/src/lib.rs index 6a196c5273..02b792e53b 100644 --- a/crates/nu-json/src/lib.rs +++ b/crates/nu-json/src/lib.rs @@ -2,7 +2,7 @@ pub use self::de::{ from_iter, from_reader, from_slice, from_str, Deserializer, StreamDeserializer, }; pub use self::error::{Error, ErrorCode, Result}; -pub use self::ser::{to_string, to_vec, to_writer, Serializer}; +pub use self::ser::{to_string, to_string_raw, to_vec, to_writer, Serializer}; pub use self::value::{from_value, to_value, Map, Value}; pub mod builder; diff --git a/crates/nu-json/src/ser.rs b/crates/nu-json/src/ser.rs index 172784c3cb..b29a988295 100644 --- a/crates/nu-json/src/ser.rs +++ b/crates/nu-json/src/ser.rs @@ -1023,3 +1023,16 @@ where let string = String::from_utf8(vec)?; Ok(string) } + +/// Encode the specified struct into a Hjson `String` buffer. +/// And remove all whitespace +#[inline] +pub fn to_string_raw(value: &T) -> Result +where + T: ser::Serialize, +{ + let vec = to_vec(value)?; + let mut string = String::from_utf8(vec)?; + string.retain(|c| !c.is_whitespace()); + Ok(string) +} diff --git a/src/tests.rs b/src/tests.rs index 097080a6d4..c8375fa860 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1324,3 +1324,11 @@ fn cjk_in_substrings() -> TestResult { "title-page.md", ) } + +#[test] +fn to_json_raw_flag() -> TestResult { + run_test( + "[[a b]; [jim susie] [3 4]] | to json -r", + r#"[{"a":"jim","b":"susie"},{"a":3,"b":4}]"#, + ) +}