1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 11:37:44 +00:00

Merge pull request #3579 from jfinkels/df-total-label-target-column

df: show "total" label in correct column
This commit is contained in:
Sylvestre Ledru 2022-05-31 07:42:06 +01:00 committed by GitHub
commit e276e652dc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 73 additions and 14 deletions

View file

@ -204,12 +204,18 @@ pub(crate) struct RowFormatter<'a> {
// numbers. We could split the options up into those groups to // numbers. We could split the options up into those groups to
// reduce the coupling between this `table.rs` module and the main // reduce the coupling between this `table.rs` module and the main
// `df.rs` module. // `df.rs` module.
/// Whether to use the special rules for displaying the total row.
is_total_row: bool,
} }
impl<'a> RowFormatter<'a> { impl<'a> RowFormatter<'a> {
/// Instantiate this struct. /// Instantiate this struct.
pub(crate) fn new(row: &'a Row, options: &'a Options) -> Self { pub(crate) fn new(row: &'a Row, options: &'a Options, is_total_row: bool) -> Self {
Self { row, options } Self {
row,
options,
is_total_row,
}
} }
/// Get a string giving the scaled version of the input number. /// Get a string giving the scaled version of the input number.
@ -251,13 +257,25 @@ impl<'a> RowFormatter<'a> {
for column in &self.options.columns { for column in &self.options.columns {
let string = match column { let string = match column {
Column::Source => self.row.fs_device.to_string(), Column::Source => {
if self.is_total_row {
"total".to_string()
} else {
self.row.fs_device.to_string()
}
}
Column::Size => self.scaled_bytes(self.row.bytes), Column::Size => self.scaled_bytes(self.row.bytes),
Column::Used => self.scaled_bytes(self.row.bytes_used), Column::Used => self.scaled_bytes(self.row.bytes_used),
Column::Avail => self.scaled_bytes(self.row.bytes_avail), Column::Avail => self.scaled_bytes(self.row.bytes_avail),
Column::Pcent => Self::percentage(self.row.bytes_usage), Column::Pcent => Self::percentage(self.row.bytes_usage),
Column::Target => self.row.fs_mount.to_string(), Column::Target => {
if self.is_total_row && !self.options.columns.contains(&Column::Source) {
"total".to_string()
} else {
self.row.fs_mount.to_string()
}
}
Column::Itotal => self.scaled_inodes(self.row.inodes), Column::Itotal => self.scaled_inodes(self.row.inodes),
Column::Iused => self.scaled_inodes(self.row.inodes_used), Column::Iused => self.scaled_inodes(self.row.inodes_used),
Column::Iavail => self.scaled_inodes(self.row.inodes_free), Column::Iavail => self.scaled_inodes(self.row.inodes_free),
@ -371,7 +389,7 @@ impl Table {
// the output table. // the output table.
if options.show_all_fs || filesystem.usage.blocks > 0 { if options.show_all_fs || filesystem.usage.blocks > 0 {
let row = Row::from(filesystem); let row = Row::from(filesystem);
let fmt = RowFormatter::new(&row, options); let fmt = RowFormatter::new(&row, options, false);
let values = fmt.get_values(); let values = fmt.get_values();
total += row; total += row;
@ -386,7 +404,7 @@ impl Table {
} }
if options.show_total { if options.show_total {
let total_row = RowFormatter::new(&total, options); let total_row = RowFormatter::new(&total, options, true);
rows.push(total_row.get_values()); rows.push(total_row.get_values());
} }
@ -625,7 +643,7 @@ mod tests {
..Default::default() ..Default::default()
}; };
let fmt = RowFormatter::new(&row, &options); let fmt = RowFormatter::new(&row, &options, false);
assert_eq!( assert_eq!(
fmt.get_values(), fmt.get_values(),
vec!("my_device", "100", "25", "75", "25%", "my_mount") vec!("my_device", "100", "25", "75", "25%", "my_mount")
@ -651,7 +669,7 @@ mod tests {
..Default::default() ..Default::default()
}; };
let fmt = RowFormatter::new(&row, &options); let fmt = RowFormatter::new(&row, &options, false);
assert_eq!( assert_eq!(
fmt.get_values(), fmt.get_values(),
vec!("my_device", "my_type", "100", "25", "75", "25%", "my_mount") vec!("my_device", "my_type", "100", "25", "75", "25%", "my_mount")
@ -676,7 +694,7 @@ mod tests {
..Default::default() ..Default::default()
}; };
let fmt = RowFormatter::new(&row, &options); let fmt = RowFormatter::new(&row, &options, false);
assert_eq!( assert_eq!(
fmt.get_values(), fmt.get_values(),
vec!("my_device", "10", "2", "8", "20%", "my_mount") vec!("my_device", "10", "2", "8", "20%", "my_mount")
@ -695,7 +713,7 @@ mod tests {
inodes: 10, inodes: 10,
..Default::default() ..Default::default()
}; };
let fmt = RowFormatter::new(&row, &options); let fmt = RowFormatter::new(&row, &options, false);
assert_eq!(fmt.get_values(), vec!("1", "10")); assert_eq!(fmt.get_values(), vec!("1", "10"));
} }
@ -718,7 +736,7 @@ mod tests {
..Default::default() ..Default::default()
}; };
let fmt = RowFormatter::new(&row, &options); let fmt = RowFormatter::new(&row, &options, false);
assert_eq!( assert_eq!(
fmt.get_values(), fmt.get_values(),
vec!("my_device", "my_type", "4k", "1k", "3k", "25%", "my_mount") vec!("my_device", "my_type", "4k", "1k", "3k", "25%", "my_mount")
@ -744,7 +762,7 @@ mod tests {
..Default::default() ..Default::default()
}; };
let fmt = RowFormatter::new(&row, &options); let fmt = RowFormatter::new(&row, &options, false);
assert_eq!( assert_eq!(
fmt.get_values(), fmt.get_values(),
vec!("my_device", "my_type", "4K", "1K", "3K", "25%", "my_mount") vec!("my_device", "my_type", "4K", "1K", "3K", "25%", "my_mount")
@ -761,7 +779,7 @@ mod tests {
bytes_usage: Some(0.251), bytes_usage: Some(0.251),
..Default::default() ..Default::default()
}; };
let fmt = RowFormatter::new(&row, &options); let fmt = RowFormatter::new(&row, &options, false);
assert_eq!(fmt.get_values(), vec!("26%")); assert_eq!(fmt.get_values(), vec!("26%"));
} }
@ -780,7 +798,7 @@ mod tests {
bytes_avail, bytes_avail,
..Default::default() ..Default::default()
}; };
RowFormatter::new(&row, &options).get_values() RowFormatter::new(&row, &options, false).get_values()
} }
assert_eq!(get_formatted_values(100, 100, 0), vec!("1", "1", "0")); assert_eq!(get_formatted_values(100, 100, 0), vec!("1", "1", "0"));

View file

@ -360,6 +360,47 @@ fn test_total() {
assert_eq!(computed_total_avail, reported_total_avail); assert_eq!(computed_total_avail, reported_total_avail);
} }
/// Test that the "total" label appears in the correct column.
///
/// The "total" label should appear in the "source" column, or in the
/// "target" column if "source" is not visible.
#[test]
fn test_total_label_in_correct_column() {
let output = new_ucmd!()
.args(&["--output=source", "--total", "."])
.succeeds()
.stdout_move_str();
let last_line = output.lines().last().unwrap();
assert_eq!(last_line.trim(), "total");
let output = new_ucmd!()
.args(&["--output=target", "--total", "."])
.succeeds()
.stdout_move_str();
let last_line = output.lines().last().unwrap();
assert_eq!(last_line.trim(), "total");
let output = new_ucmd!()
.args(&["--output=source,target", "--total", "."])
.succeeds()
.stdout_move_str();
let last_line = output.lines().last().unwrap();
assert_eq!(
last_line.split_whitespace().collect::<Vec<&str>>(),
vec!["total", "-"]
);
let output = new_ucmd!()
.args(&["--output=target,source", "--total", "."])
.succeeds()
.stdout_move_str();
let last_line = output.lines().last().unwrap();
assert_eq!(
last_line.split_whitespace().collect::<Vec<&str>>(),
vec!["-", "total"]
);
}
#[test] #[test]
fn test_use_percentage() { fn test_use_percentage() {
let output = new_ucmd!() let output = new_ucmd!()