Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 48 additions & 9 deletions src/uu/df/src/df.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,60 @@ struct FsSelector {
exclude: HashSet<String>,
}

/// A block size to use in condensing the display of a large number of bytes.
///
/// The [`Bytes`] variant represents a static block size. The
/// [`HumanReadableDecimal`] and [`HumanReadableBinary`] variants
/// represent dynamic block sizes: as the number of bytes increases,
/// the divisor increases as well (for example, from 1 to 1,000 to
/// 1,000,000 and so on in the case of [`HumanReadableDecimal`]).
///
/// The default variant is `Bytes(1024)`.
enum BlockSize {
/// A fixed number of bytes.
///
/// The number must be positive.
Bytes(u64),

/// Use the largest divisor corresponding to a unit, like B, K, M, G, etc.
///
/// This variant represents powers of 1,000. Contrast with
/// [`HumanReadableBinary`], which represents powers of 1,024.
HumanReadableDecimal,

/// Use the largest divisor corresponding to a unit, like B, K, M, G, etc.
///
/// This variant represents powers of 1,000. Contrast with
/// [`HumanReadableBinary`], which represents powers of 1,024.
HumanReadableBinary,
}

impl Default for BlockSize {
fn default() -> Self {
Self::Bytes(1024)
}
}

impl From<&ArgMatches> for BlockSize {
fn from(matches: &ArgMatches) -> Self {
if matches.is_present(OPT_HUMAN_READABLE) {
Self::HumanReadableBinary
} else if matches.is_present(OPT_HUMAN_READABLE_2) {
Self::HumanReadableDecimal
} else {
Self::default()
}
}
}

#[derive(Default)]
struct Options {
show_local_fs: bool,
show_all_fs: bool,
show_listed_fs: bool,
show_fs_type: bool,
show_inode_instead: bool,
// block_size: usize,
human_readable_base: i64,
block_size: BlockSize,
fs_selector: FsSelector,
}

Expand All @@ -82,13 +127,7 @@ impl Options {
show_listed_fs: false,
show_fs_type: matches.is_present(OPT_PRINT_TYPE),
show_inode_instead: matches.is_present(OPT_INODES),
human_readable_base: if matches.is_present(OPT_HUMAN_READABLE) {
1024
} else if matches.is_present(OPT_HUMAN_READABLE_2) {
1000
} else {
-1
},
block_size: BlockSize::from(matches),
fs_selector: FsSelector::from(matches),
}
}
Expand Down
50 changes: 17 additions & 33 deletions src/uu/df/src/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
//! [`DisplayRow`] implements [`std::fmt::Display`].
use number_prefix::NumberPrefix;

use crate::{Filesystem, Options};
use crate::{BlockSize, Filesystem, Options};
use uucore::fsext::{FsUsage, MountInfo};

use std::fmt;
Expand Down Expand Up @@ -147,23 +147,10 @@ impl<'a> DisplayRow<'a> {
///
/// If the scaling factor is not 1000, 1024, or a negative number.
fn scaled(&self, size: u64) -> Result<String, fmt::Error> {
// TODO The argument-parsing code should be responsible for
// ensuring that the `human_readable_base` number is
// positive. Then we could remove the `Err` case from this
// function.
//
// TODO We should not be using a negative number to indicate
// default behavior. The default behavior for `df` is to show
// sizes in blocks of 1K bytes each, so we should just do
// that.
//
// TODO Support arbitrary positive scaling factors (from the
// `--block-size` command-line argument).
let number_prefix = match self.options.human_readable_base {
1000 => NumberPrefix::decimal(size as f64),
1024 => NumberPrefix::binary(size as f64),
d if d < 0 => return Ok(size.to_string()),
_ => return Err(fmt::Error {}),
let number_prefix = match self.options.block_size {
BlockSize::HumanReadableDecimal => NumberPrefix::decimal(size as f64),
BlockSize::HumanReadableBinary => NumberPrefix::binary(size as f64),
BlockSize::Bytes(d) => return Ok((size / d).to_string()),
};
match number_prefix {
NumberPrefix::Standalone(bytes) => Ok(bytes.to_string()),
Expand Down Expand Up @@ -261,7 +248,9 @@ impl fmt::Display for Header<'_> {
write!(f, "{0: >12} ", "IFree")?;
write!(f, "{0: >5} ", "IUse%")?;
} else {
if self.options.human_readable_base == -1 {
// TODO Support arbitrary positive scaling factors (from
// the `--block-size` command-line argument).
if let BlockSize::Bytes(_) = self.options.block_size {
write!(f, "{0: >12} ", "1k-blocks")?;
} else {
write!(f, "{0: >12} ", "Size")?;
Expand All @@ -281,14 +270,11 @@ impl fmt::Display for Header<'_> {
mod tests {

use crate::table::{DisplayRow, Header, Row};
use crate::Options;
use crate::{BlockSize, Options};

#[test]
fn test_header_display() {
let options = Options {
human_readable_base: -1,
..Default::default()
};
let options = Default::default();
assert_eq!(
Header::new(&options).to_string(),
"Filesystem 1k-blocks Used Available Use% Mounted on "
Expand All @@ -298,7 +284,6 @@ mod tests {
#[test]
fn test_header_display_fs_type() {
let options = Options {
human_readable_base: -1,
show_fs_type: true,
..Default::default()
};
Expand All @@ -311,7 +296,6 @@ mod tests {
#[test]
fn test_header_display_inode() {
let options = Options {
human_readable_base: -1,
show_inode_instead: true,
..Default::default()
};
Expand All @@ -324,7 +308,7 @@ mod tests {
#[test]
fn test_header_display_human_readable_binary() {
let options = Options {
human_readable_base: 1024,
block_size: BlockSize::HumanReadableBinary,
..Default::default()
};
assert_eq!(
Expand All @@ -336,7 +320,7 @@ mod tests {
#[test]
fn test_header_display_human_readable_si() {
let options = Options {
human_readable_base: 1000,
block_size: BlockSize::HumanReadableDecimal,
..Default::default()
};
assert_eq!(
Expand All @@ -348,7 +332,7 @@ mod tests {
#[test]
fn test_row_display() {
let options = Options {
human_readable_base: -1,
block_size: BlockSize::Bytes(1),
..Default::default()
};
let row = Row {
Expand Down Expand Up @@ -378,7 +362,7 @@ mod tests {
#[test]
fn test_row_display_fs_type() {
let options = Options {
human_readable_base: -1,
block_size: BlockSize::Bytes(1),
show_fs_type: true,
..Default::default()
};
Expand Down Expand Up @@ -409,7 +393,7 @@ mod tests {
#[test]
fn test_row_display_inodes() {
let options = Options {
human_readable_base: -1,
block_size: BlockSize::Bytes(1),
show_inode_instead: true,
..Default::default()
};
Expand Down Expand Up @@ -440,7 +424,7 @@ mod tests {
#[test]
fn test_row_display_human_readable_si() {
let options = Options {
human_readable_base: 1000,
block_size: BlockSize::HumanReadableDecimal,
show_fs_type: true,
..Default::default()
};
Expand Down Expand Up @@ -471,7 +455,7 @@ mod tests {
#[test]
fn test_row_display_human_readable_binary() {
let options = Options {
human_readable_base: 1024,
block_size: BlockSize::HumanReadableBinary,
show_fs_type: true,
..Default::default()
};
Expand Down