From 52f4c4ba7e30722e7af9776a3cd6a767db27a514 Mon Sep 17 00:00:00 2001 From: Daniel Reilly Date: Thu, 3 Mar 2022 13:15:13 -0500 Subject: [PATCH] Adds tab indentation option for JSON files. (#4705) --- crates/nu-command/src/formats/to/json.rs | 11 ++++++- crates/nu-json/src/lib.rs | 3 +- crates/nu-json/src/ser.rs | 37 ++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/crates/nu-command/src/formats/to/json.rs b/crates/nu-command/src/formats/to/json.rs index 5d9b3b8a6e..b440bb05da 100644 --- a/crates/nu-command/src/formats/to/json.rs +++ b/crates/nu-command/src/formats/to/json.rs @@ -22,6 +22,12 @@ impl Command for ToJson { "specify indentation width", Some('i'), ) + .named( + "tabs", + SyntaxShape::Number, + "specify indentation tab quantity", + Some('t'), + ) .category(Category::Formats) } @@ -37,6 +43,7 @@ impl Command for ToJson { input: PipelineData, ) -> Result { let raw = call.has_flag("raw"); + let use_tabs = call.has_flag("tabs"); let span = call.head; let value = input.into_value(span); @@ -44,9 +51,11 @@ impl Command for ToJson { let json_result = if raw { nu_json::to_string_raw(&json_value) + } else if use_tabs { + let tab_count: usize = call.get_flag(engine_state, stack, "tabs")?.unwrap_or(1); + nu_json::to_string_with_tab_indentation(&json_value, tab_count) } else { let indent: usize = call.get_flag(engine_state, stack, "indent")?.unwrap_or(2); - nu_json::to_string_with_indent(&json_value, indent) }; diff --git a/crates/nu-json/src/lib.rs b/crates/nu-json/src/lib.rs index d05d6c6162..eead282786 100644 --- a/crates/nu-json/src/lib.rs +++ b/crates/nu-json/src/lib.rs @@ -3,7 +3,8 @@ pub use self::de::{ }; pub use self::error::{Error, ErrorCode, Result}; pub use self::ser::{ - to_string, to_string_raw, to_string_with_indent, to_vec, to_writer, Serializer, + to_string, to_string_raw, to_string_with_indent, to_string_with_tab_indentation, to_vec, + to_writer, Serializer, }; pub use self::value::{from_value, to_value, Map, Value}; diff --git a/crates/nu-json/src/ser.rs b/crates/nu-json/src/ser.rs index 48a887c079..417011dbfc 100644 --- a/crates/nu-json/src/ser.rs +++ b/crates/nu-json/src/ser.rs @@ -946,6 +946,19 @@ where Ok(()) } +/// Encode the specified struct into a Hjson `[u8]` writer. +#[inline] +pub fn to_writer_with_tab_indentation(writer: &mut W, value: &T, tabs: usize) -> Result<()> +where + W: io::Write, + T: ser::Serialize, +{ + let indent_string = "\t".repeat(tabs); + let mut ser = Serializer::with_indent(writer, indent_string.as_bytes()); + value.serialize(&mut ser)?; + Ok(()) +} + /// Encode the specified struct into a Hjson `[u8]` writer. #[inline] pub fn to_writer_with_indent(writer: &mut W, value: &T, indent: usize) -> Result<()> @@ -972,6 +985,19 @@ where Ok(writer) } +/// Encode the specified struct into a Hjson `[u8]` buffer. +#[inline] +pub fn to_vec_with_tab_indentation(value: &T, tabs: usize) -> Result> +where + T: ser::Serialize, +{ + // We are writing to a Vec, which doesn't fail. So we can ignore + // the error. + let mut writer = Vec::with_capacity(128); + to_writer_with_tab_indentation(&mut writer, value, tabs)?; + Ok(writer) +} + /// Encode the specified struct into a Hjson `[u8]` buffer. #[inline] pub fn to_vec_with_indent(value: &T, indent: usize) -> Result> @@ -1007,6 +1033,17 @@ where Ok(string) } +/// Encode the specified struct into a Hjson `String` buffer. +#[inline] +pub fn to_string_with_tab_indentation(value: &T, tabs: usize) -> Result +where + T: ser::Serialize, +{ + let vec = to_vec_with_tab_indentation(value, tabs)?; + let string = String::from_utf8(vec)?; + Ok(string) +} + /// Encode the specified struct into a Hjson `String` buffer. /// And remove all whitespace #[inline]