@ -7,7 +7,7 @@ mod utils;
|
|||||||
|
|
||||||
use clap::{crate_version, Command};
|
use clap::{crate_version, Command};
|
||||||
use clap::{Arg, ArgAction};
|
use clap::{Arg, ArgAction};
|
||||||
use serde::Deserialize;
|
use serde::{Deserialize, Serialize};
|
||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::{self, BufRead, BufReader};
|
use std::io::{self, BufRead, BufReader};
|
||||||
@ -16,7 +16,11 @@ use std::str::FromStr;
|
|||||||
use uucore::{error::UResult, format_usage, help_about, help_usage};
|
use uucore::{error::UResult, format_usage, help_about, help_usage};
|
||||||
|
|
||||||
use tabled::{
|
use tabled::{
|
||||||
settings::{location::ByColumnName, object, Alignment, Disable, Modify, Style},
|
settings::{
|
||||||
|
location::ByColumnName,
|
||||||
|
object::{self, Rows},
|
||||||
|
Alignment, Disable, Modify, Style,
|
||||||
|
},
|
||||||
Table, Tabled,
|
Table, Tabled,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -25,6 +29,10 @@ const USAGE: &str = help_usage!("lsmem.md");
|
|||||||
|
|
||||||
mod options {
|
mod options {
|
||||||
pub const BYTES: &str = "bytes";
|
pub const BYTES: &str = "bytes";
|
||||||
|
pub const NOHEADINGS: &str = "noheadings";
|
||||||
|
pub const JSON: &str = "json";
|
||||||
|
pub const PAIRS: &str = "pairs";
|
||||||
|
pub const RAW: &str = "raw";
|
||||||
}
|
}
|
||||||
|
|
||||||
// const BUFSIZ: usize = 1024;
|
// const BUFSIZ: usize = 1024;
|
||||||
@ -186,7 +194,7 @@ impl MemoryBlock {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Tabled, Default)]
|
#[derive(Tabled, Default, Serialize)]
|
||||||
struct TableRow {
|
struct TableRow {
|
||||||
#[tabled(rename = "RANGE")]
|
#[tabled(rename = "RANGE")]
|
||||||
range: String,
|
range: String,
|
||||||
@ -199,18 +207,39 @@ struct TableRow {
|
|||||||
#[tabled(rename = "BLOCK")]
|
#[tabled(rename = "BLOCK")]
|
||||||
block: String,
|
block: String,
|
||||||
#[tabled(rename = "NODE")]
|
#[tabled(rename = "NODE")]
|
||||||
|
#[serde(skip_serializing)]
|
||||||
node: String,
|
node: String,
|
||||||
#[tabled(rename = "ZONES")]
|
#[tabled(rename = "ZONES")]
|
||||||
|
#[serde(skip_serializing)]
|
||||||
zones: String,
|
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
|
||||||
|
)
|
||||||
|
}
|
||||||
|
fn to_raw_string(&self) -> String {
|
||||||
|
format!(
|
||||||
|
r#"{} {} {} {} {}"#,
|
||||||
|
self.range, self.size, self.state, self.removable, self.block
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
struct TableRowJson {
|
||||||
|
memory: Vec<TableRow>,
|
||||||
|
}
|
||||||
|
|
||||||
struct Options {
|
struct Options {
|
||||||
have_nodes: bool,
|
have_nodes: bool,
|
||||||
// raw: bool,
|
raw: bool,
|
||||||
// export: bool,
|
export: bool,
|
||||||
// json: bool,
|
json: bool,
|
||||||
// noheadings: bool,
|
noheadings: bool,
|
||||||
// summary: bool,
|
|
||||||
list_all: bool,
|
list_all: bool,
|
||||||
bytes: bool,
|
bytes: bool,
|
||||||
want_summary: bool,
|
want_summary: bool,
|
||||||
@ -250,11 +279,10 @@ impl Options {
|
|||||||
fn new() -> Options {
|
fn new() -> Options {
|
||||||
Options {
|
Options {
|
||||||
have_nodes: false,
|
have_nodes: false,
|
||||||
// raw: false,
|
raw: false,
|
||||||
// export: false,
|
export: false,
|
||||||
// json: false,
|
json: false,
|
||||||
// noheadings: false,
|
noheadings: false,
|
||||||
// summary: false,
|
|
||||||
list_all: false,
|
list_all: false,
|
||||||
bytes: false,
|
bytes: false,
|
||||||
want_summary: true, // default true
|
want_summary: true, // default true
|
||||||
@ -413,8 +441,8 @@ fn memory_block_read_attrs(opts: &Options, path: &PathBuf) -> MemoryBlock {
|
|||||||
blk
|
blk
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_table(lsmem: &Lsmem, opts: &Options) -> tabled::Table {
|
fn create_table_rows(lsmem: &Lsmem, opts: &Options) -> Vec<TableRow> {
|
||||||
let mut table = Vec::<TableRow>::new();
|
let mut table_rows = Vec::<TableRow>::new();
|
||||||
|
|
||||||
for i in 0..lsmem.nblocks {
|
for i in 0..lsmem.nblocks {
|
||||||
let mut row = TableRow::default();
|
let mut row = TableRow::default();
|
||||||
@ -460,13 +488,13 @@ fn create_table(lsmem: &Lsmem, opts: &Options) -> tabled::Table {
|
|||||||
row.node = format!("{}", blk.node);
|
row.node = format!("{}", blk.node);
|
||||||
}
|
}
|
||||||
|
|
||||||
table.push(row);
|
table_rows.push(row);
|
||||||
}
|
}
|
||||||
Table::new(table)
|
table_rows
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_table(lsmem: &Lsmem, opts: &Options) {
|
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
|
table
|
||||||
.with(Style::blank())
|
.with(Style::blank())
|
||||||
.with(Modify::new(object::Columns::new(1..)).with(Alignment::right()));
|
.with(Modify::new(object::Columns::new(1..)).with(Alignment::right()));
|
||||||
@ -475,9 +503,47 @@ fn print_table(lsmem: &Lsmem, opts: &Options) {
|
|||||||
table.with(Disable::column(ByColumnName::new("NODE")));
|
table.with(Disable::column(ByColumnName::new("NODE")));
|
||||||
table.with(Disable::column(ByColumnName::new("ZONES")));
|
table.with(Disable::column(ByColumnName::new("ZONES")));
|
||||||
|
|
||||||
|
if opts.noheadings {
|
||||||
|
table.with(Disable::row(Rows::first()));
|
||||||
|
}
|
||||||
|
|
||||||
println!("{table}");
|
println!("{table}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn print_json(lsmem: &Lsmem, opts: &Options) {
|
||||||
|
let table_json = TableRowJson {
|
||||||
|
memory: create_table_rows(lsmem, opts),
|
||||||
|
};
|
||||||
|
|
||||||
|
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 table_pairs_string = table_rows
|
||||||
|
.into_iter()
|
||||||
|
.map(|row| row.to_pairs_string())
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.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_raw_string += &row.to_raw_string();
|
||||||
|
table_raw_string += "\n";
|
||||||
|
}
|
||||||
|
// remove the last newline
|
||||||
|
table_raw_string.pop();
|
||||||
|
println!("RANGE SIZE STATE REMOVABLE BLOCK");
|
||||||
|
println!("{table_raw_string}");
|
||||||
|
}
|
||||||
|
|
||||||
fn print_summary(lsmem: &Lsmem, opts: &Options) {
|
fn print_summary(lsmem: &Lsmem, opts: &Options) {
|
||||||
if opts.bytes {
|
if opts.bytes {
|
||||||
println!("{:<23} {:>15}", "Memory block size:", lsmem.block_size);
|
println!("{:<23} {:>15}", "Memory block size:", lsmem.block_size);
|
||||||
@ -516,16 +582,31 @@ where
|
|||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let matches: clap::ArgMatches = uu_app().try_get_matches_from(args)?;
|
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 lsmem = Lsmem::new();
|
||||||
let mut opts = Options::new();
|
let mut opts = Options::new();
|
||||||
opts.bytes = opt_bytes;
|
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);
|
||||||
|
opts.raw = matches.get_flag(options::RAW);
|
||||||
|
|
||||||
|
if opts.json || opts.export || opts.raw {
|
||||||
|
opts.want_summary = false;
|
||||||
|
}
|
||||||
|
|
||||||
read_info(&mut lsmem, &mut opts);
|
read_info(&mut lsmem, &mut opts);
|
||||||
|
|
||||||
if opts.want_table {
|
if opts.want_table {
|
||||||
print_table(&lsmem, &opts);
|
if opts.json {
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.want_summary {
|
if opts.want_summary {
|
||||||
@ -548,4 +629,35 @@ pub fn uu_app() -> Command {
|
|||||||
.help("print SIZE in bytes rather than in human readable format")
|
.help("print SIZE in bytes rather than in human readable format")
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new(options::NOHEADINGS)
|
||||||
|
.short('n')
|
||||||
|
.long("noheadings")
|
||||||
|
.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)
|
||||||
|
.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)
|
||||||
|
.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]),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user