From f83d22b3eaaca7846c43d1132dfac6e3be555208 Mon Sep 17 00:00:00 2001 From: Yang Hau Date: Mon, 26 Aug 2024 00:56:31 +0800 Subject: [PATCH 1/4] lsmem: Add noheadings --- src/uu/lsmem/src/lsmem.rs | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/uu/lsmem/src/lsmem.rs b/src/uu/lsmem/src/lsmem.rs index 89cf111..910dc3d 100644 --- a/src/uu/lsmem/src/lsmem.rs +++ b/src/uu/lsmem/src/lsmem.rs @@ -16,7 +16,11 @@ use std::str::FromStr; use uucore::{error::UResult, format_usage, help_about, help_usage}; use tabled::{ - settings::{location::ByColumnName, object, Alignment, Disable, Modify, Style}, + settings::{ + location::ByColumnName, + object::{self, Rows}, + Alignment, Disable, Modify, Style, + }, Table, Tabled, }; @@ -25,6 +29,7 @@ const USAGE: &str = help_usage!("lsmem.md"); mod options { pub const BYTES: &str = "bytes"; + pub const NOHEADINGS: &str = "noheadings"; } // const BUFSIZ: usize = 1024; @@ -209,7 +214,7 @@ struct Options { // raw: bool, // export: bool, // json: bool, - // noheadings: bool, + noheadings: bool, // summary: bool, list_all: bool, bytes: bool, @@ -253,7 +258,7 @@ impl Options { // raw: false, // export: false, // json: false, - // noheadings: false, + noheadings: false, // summary: false, list_all: false, bytes: false, @@ -475,6 +480,10 @@ fn print_table(lsmem: &Lsmem, opts: &Options) { table.with(Disable::column(ByColumnName::new("NODE"))); table.with(Disable::column(ByColumnName::new("ZONES"))); + if opts.noheadings { + table.with(Disable::row(Rows::first())); + } + println!("{table}"); } @@ -516,11 +525,11 @@ where #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { let matches: clap::ArgMatches = uu_app().try_get_matches_from(args)?; - let opt_bytes = matches.get_flag(options::BYTES); let mut lsmem = Lsmem::new(); let mut opts = Options::new(); - opts.bytes = opt_bytes; + opts.bytes = matches.get_flag(options::BYTES); + opts.noheadings = matches.get_flag(options::NOHEADINGS); read_info(&mut lsmem, &mut opts); @@ -548,4 +557,11 @@ pub fn uu_app() -> Command { .help("print SIZE in bytes rather than in human readable format") .action(ArgAction::SetTrue), ) + .arg( + Arg::new(options::NOHEADINGS) + .short('n') + .long("noheadings") + .help("don't print headings") + .action(ArgAction::SetTrue), + ) } From 3aef200dc1f8ddef031a28a191158fd215da26b4 Mon Sep 17 00:00:00 2001 From: Yang Hau Date: Mon, 26 Aug 2024 01:23:42 +0800 Subject: [PATCH 2/4] lsmem: Add option json --- src/uu/lsmem/src/lsmem.rs | 51 ++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/src/uu/lsmem/src/lsmem.rs b/src/uu/lsmem/src/lsmem.rs index 910dc3d..c0a3eea 100644 --- a/src/uu/lsmem/src/lsmem.rs +++ b/src/uu/lsmem/src/lsmem.rs @@ -7,7 +7,7 @@ mod utils; use clap::{crate_version, Command}; use clap::{Arg, ArgAction}; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; use std::borrow::Borrow; use std::fs; use std::io::{self, BufRead, BufReader}; @@ -30,6 +30,7 @@ const USAGE: &str = help_usage!("lsmem.md"); mod options { pub const BYTES: &str = "bytes"; pub const NOHEADINGS: &str = "noheadings"; + pub const JSON: &str = "json"; } // const BUFSIZ: usize = 1024; @@ -191,7 +192,7 @@ impl MemoryBlock { } } -#[derive(Tabled, Default)] +#[derive(Tabled, Default, Serialize)] struct TableRow { #[tabled(rename = "RANGE")] range: String, @@ -204,16 +205,23 @@ struct TableRow { #[tabled(rename = "BLOCK")] block: String, #[tabled(rename = "NODE")] + #[serde(skip_serializing)] node: String, #[tabled(rename = "ZONES")] + #[serde(skip_serializing)] zones: String, } +#[derive(Serialize)] +struct TableRowJson { + memory: Vec, +} + struct Options { have_nodes: bool, // raw: bool, // export: bool, - // json: bool, + json: bool, noheadings: bool, // summary: bool, list_all: bool, @@ -257,7 +265,7 @@ impl Options { have_nodes: false, // raw: false, // export: false, - // json: false, + json: false, noheadings: false, // summary: false, list_all: false, @@ -418,8 +426,8 @@ fn memory_block_read_attrs(opts: &Options, path: &PathBuf) -> MemoryBlock { blk } -fn create_table(lsmem: &Lsmem, opts: &Options) -> tabled::Table { - let mut table = Vec::::new(); +fn create_table_rows(lsmem: &Lsmem, opts: &Options) -> Vec { + let mut table_rows = Vec::::new(); for i in 0..lsmem.nblocks { let mut row = TableRow::default(); @@ -465,13 +473,13 @@ fn create_table(lsmem: &Lsmem, opts: &Options) -> tabled::Table { row.node = format!("{}", blk.node); } - table.push(row); + table_rows.push(row); } - Table::new(table) + table_rows } fn print_table(lsmem: &Lsmem, opts: &Options) { - let mut table = create_table(lsmem, opts); + let mut table = Table::new(create_table_rows(lsmem, opts)); table .with(Style::blank()) .with(Modify::new(object::Columns::new(1..)).with(Alignment::right())); @@ -487,6 +495,15 @@ fn print_table(lsmem: &Lsmem, opts: &Options) { println!("{table}"); } +fn print_json(lsmem: &Lsmem, opts: &Options) { + let table_json = TableRowJson { + memory: create_table_rows(lsmem, opts), + }; + + let table_json_string = serde_json::to_string_pretty(&table_json).unwrap(); + println!("{table_json_string}"); +} + fn print_summary(lsmem: &Lsmem, opts: &Options) { if opts.bytes { println!("{:<23} {:>15}", "Memory block size:", lsmem.block_size); @@ -530,14 +547,19 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let mut opts = Options::new(); opts.bytes = matches.get_flag(options::BYTES); opts.noheadings = matches.get_flag(options::NOHEADINGS); + opts.json = matches.get_flag(options::JSON); read_info(&mut lsmem, &mut opts); if opts.want_table { - print_table(&lsmem, &opts); + if opts.json { + print_json(&lsmem, &opts); + } else { + print_table(&lsmem, &opts); + } } - if opts.want_summary { + if opts.want_summary && !opts.json { print_summary(&lsmem, &opts); } @@ -564,4 +586,11 @@ pub fn uu_app() -> Command { .help("don't print headings") .action(ArgAction::SetTrue), ) + .arg( + Arg::new(options::JSON) + .short('J') + .long("json") + .help("use JSON output format") + .action(ArgAction::SetTrue), + ) } From 422e21106fafb9052aad4067a891adda84eabc92 Mon Sep 17 00:00:00 2001 From: Yang Hau Date: Mon, 26 Aug 2024 01:52:38 +0800 Subject: [PATCH 3/4] lsmem: Add option pairs --- src/uu/lsmem/src/lsmem.rs | 42 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/src/uu/lsmem/src/lsmem.rs b/src/uu/lsmem/src/lsmem.rs index c0a3eea..da309a1 100644 --- a/src/uu/lsmem/src/lsmem.rs +++ b/src/uu/lsmem/src/lsmem.rs @@ -31,6 +31,7 @@ mod options { pub const BYTES: &str = "bytes"; pub const NOHEADINGS: &str = "noheadings"; pub const JSON: &str = "json"; + pub const PAIRS: &str = "pairs"; } // const BUFSIZ: usize = 1024; @@ -212,6 +213,15 @@ struct TableRow { zones: String, } +impl TableRow { + fn to_pairs_string(&self) -> String { + format!( + r#"RANGE="{}" SIZE="{}" STATE="{}" REMOVABLE="{}" BLOCK="{}""#, + self.range, self.size, self.state, self.removable, self.block + ) + } +} + #[derive(Serialize)] struct TableRowJson { memory: Vec, @@ -220,7 +230,7 @@ struct TableRowJson { struct Options { have_nodes: bool, // raw: bool, - // export: bool, + export: bool, json: bool, noheadings: bool, // summary: bool, @@ -264,7 +274,7 @@ impl Options { Options { have_nodes: false, // raw: false, - // export: false, + export: false, json: false, noheadings: false, // summary: false, @@ -504,6 +514,18 @@ fn print_json(lsmem: &Lsmem, opts: &Options) { println!("{table_json_string}"); } +fn print_pairs(lsmem: &Lsmem, opts: &Options) { + let table_rows = create_table_rows(lsmem, opts); + let mut table_pairs_string = String::new(); + for row in table_rows { + table_pairs_string += &row.to_pairs_string(); + table_pairs_string += "\n"; + } + // remove the last newline + table_pairs_string.pop(); + println!("{table_pairs_string}"); +} + fn print_summary(lsmem: &Lsmem, opts: &Options) { if opts.bytes { println!("{:<23} {:>15}", "Memory block size:", lsmem.block_size); @@ -548,18 +570,25 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { opts.bytes = matches.get_flag(options::BYTES); opts.noheadings = matches.get_flag(options::NOHEADINGS); opts.json = matches.get_flag(options::JSON); + opts.export = matches.get_flag(options::PAIRS); + + if opts.json || opts.export { + opts.want_summary = false; + } read_info(&mut lsmem, &mut opts); if opts.want_table { if opts.json { print_json(&lsmem, &opts); + } else if opts.export { + print_pairs(&lsmem, &opts); } else { print_table(&lsmem, &opts); } } - if opts.want_summary && !opts.json { + if opts.want_summary { print_summary(&lsmem, &opts); } @@ -593,4 +622,11 @@ pub fn uu_app() -> Command { .help("use JSON output format") .action(ArgAction::SetTrue), ) + .arg( + Arg::new(options::PAIRS) + .short('P') + .long("pairs") + .help("use key=\"value\" output format") + .action(ArgAction::SetTrue), + ) } From 6f7dc259c9582cae6f2187fb1d553fa1949a8a20 Mon Sep 17 00:00:00 2001 From: Yang Hau Date: Mon, 26 Aug 2024 01:58:59 +0800 Subject: [PATCH 4/4] lsmem: Add option raw --- src/uu/lsmem/src/lsmem.rs | 57 ++++++++++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 13 deletions(-) diff --git a/src/uu/lsmem/src/lsmem.rs b/src/uu/lsmem/src/lsmem.rs index da309a1..5622140 100644 --- a/src/uu/lsmem/src/lsmem.rs +++ b/src/uu/lsmem/src/lsmem.rs @@ -32,6 +32,7 @@ mod options { pub const NOHEADINGS: &str = "noheadings"; pub const JSON: &str = "json"; pub const PAIRS: &str = "pairs"; + pub const RAW: &str = "raw"; } // const BUFSIZ: usize = 1024; @@ -220,6 +221,12 @@ impl TableRow { self.range, self.size, self.state, self.removable, self.block ) } + fn to_raw_string(&self) -> String { + format!( + r#"{} {} {} {} {}"#, + self.range, self.size, self.state, self.removable, self.block + ) + } } #[derive(Serialize)] @@ -229,11 +236,10 @@ struct TableRowJson { struct Options { have_nodes: bool, - // raw: bool, + raw: bool, export: bool, json: bool, noheadings: bool, - // summary: bool, list_all: bool, bytes: bool, want_summary: bool, @@ -273,11 +279,10 @@ impl Options { fn new() -> Options { Options { have_nodes: false, - // raw: false, + raw: false, export: false, json: false, noheadings: false, - // summary: false, list_all: false, bytes: false, want_summary: true, // default true @@ -510,20 +515,33 @@ fn print_json(lsmem: &Lsmem, opts: &Options) { memory: create_table_rows(lsmem, opts), }; - let table_json_string = serde_json::to_string_pretty(&table_json).unwrap(); + let mut table_json_string = serde_json::to_string_pretty(&table_json).unwrap(); + table_json_string = table_json_string.replace("\"yes\"", "true"); + table_json_string = table_json_string.replace("\"no\"", "false"); println!("{table_json_string}"); } fn print_pairs(lsmem: &Lsmem, opts: &Options) { let table_rows = create_table_rows(lsmem, opts); - let mut table_pairs_string = String::new(); + let table_pairs_string = table_rows + .into_iter() + .map(|row| row.to_pairs_string()) + .collect::>() + .join("\n"); + println!("{table_pairs_string}"); +} + +fn print_raw(lsmem: &Lsmem, opts: &Options) { + let table_rows = create_table_rows(lsmem, opts); + let mut table_raw_string = String::new(); for row in table_rows { - table_pairs_string += &row.to_pairs_string(); - table_pairs_string += "\n"; + table_raw_string += &row.to_raw_string(); + table_raw_string += "\n"; } // remove the last newline - table_pairs_string.pop(); - println!("{table_pairs_string}"); + table_raw_string.pop(); + println!("RANGE SIZE STATE REMOVABLE BLOCK"); + println!("{table_raw_string}"); } fn print_summary(lsmem: &Lsmem, opts: &Options) { @@ -571,8 +589,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { opts.noheadings = matches.get_flag(options::NOHEADINGS); opts.json = matches.get_flag(options::JSON); opts.export = matches.get_flag(options::PAIRS); + opts.raw = matches.get_flag(options::RAW); - if opts.json || opts.export { + if opts.json || opts.export || opts.raw { opts.want_summary = false; } @@ -583,6 +602,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { print_json(&lsmem, &opts); } else if opts.export { print_pairs(&lsmem, &opts); + } else if opts.raw { + print_raw(&lsmem, &opts); } else { print_table(&lsmem, &opts); } @@ -620,13 +641,23 @@ pub fn uu_app() -> Command { .short('J') .long("json") .help("use JSON output format") - .action(ArgAction::SetTrue), + .action(ArgAction::SetTrue) + .conflicts_with_all([options::PAIRS, options::RAW]), ) .arg( Arg::new(options::PAIRS) .short('P') .long("pairs") .help("use key=\"value\" output format") - .action(ArgAction::SetTrue), + .action(ArgAction::SetTrue) + .conflicts_with_all([options::JSON, options::RAW]), + ) + .arg( + Arg::new(options::RAW) + .short('r') + .long("raw") + .help("use raw output format") + .action(ArgAction::SetTrue) + .conflicts_with_all([options::JSON, options::PAIRS]), ) }