diff --git a/src/display_node.rs b/src/display_node.rs index 7f1f6276..9a4bcbcf 100644 --- a/src/display_node.rs +++ b/src/display_node.rs @@ -1,8 +1,12 @@ +use std::cell::RefCell; use std::path::PathBuf; -use serde::Serialize; +use serde::ser::SerializeStruct; +use serde::{Serialize, Serializer}; -#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Serialize)] +use crate::display::human_readable_number; + +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] pub struct DisplayNode { // Note: the order of fields in important here, for PartialEq and PartialOrd pub size: u64, @@ -25,3 +29,30 @@ impl DisplayNode { out } } + +// Only used for -j 'json' flag combined with -o 'output_type' flag +// Used to pass the output_type into the custom Serde serializer +thread_local! { + pub static OUTPUT_TYPE: RefCell = const { RefCell::new(String::new()) }; +} + +/* +We need the custom Serialize incase someone uses the -o flag to pass a custom output type in +(show size in Mb / Gb etc). +Sadly this also necessitates a global variable OUTPUT_TYPE as we can not pass the output_type flag +into the serialize method + */ +impl Serialize for DisplayNode { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let readable_size = OUTPUT_TYPE + .with(|output_type| human_readable_number(self.size, output_type.borrow().as_str())); + let mut state = serializer.serialize_struct("DisplayNode", 2)?; + state.serialize_field("size", &(readable_size))?; + state.serialize_field("name", &self.name)?; + state.serialize_field("children", &self.children)?; + state.end() + } +} diff --git a/src/main.rs b/src/main.rs index ddc50ee1..823459ea 100644 --- a/src/main.rs +++ b/src/main.rs @@ -33,6 +33,7 @@ use sysinfo::{System, SystemExt}; use self::display::draw_it; use config::get_config; use dir_walker::walk_it; +use display_node::OUTPUT_TYPE; use filter::get_biggest; use filter_type::get_all_file_types; use regex::Regex; @@ -327,20 +328,24 @@ fn main() { } if let Some(root_node) = tree { - let idd = InitialDisplayData { - short_paths: !config.get_full_paths(&options), - is_reversed: !config.get_reverse(&options), - colors_on: is_colors, - by_filecount, - by_filetime, - is_screen_reader: config.get_screen_reader(&options), - output_format, - bars_on_right: config.get_bars_on_right(&options), - }; - if config.get_output_json(&options) { + OUTPUT_TYPE.with(|wrapped| { + wrapped.replace(output_format); + }); println!("{}", serde_json::to_string(&root_node).unwrap()); } else { + let idd = InitialDisplayData { + short_paths: !config.get_full_paths(&options), + is_reversed: !config.get_reverse(&options), + colors_on: is_colors, + by_filecount, + by_filetime, + is_screen_reader: config.get_screen_reader(&options), + output_format, + bars_on_right: config.get_bars_on_right(&options), + }; + + draw_it( idd, config.get_no_bars(&options),