diff --git a/Cargo.lock b/Cargo.lock index 0bcd358..397b759 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "ascii_table" version = "3.0.2" @@ -11,13 +13,21 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "bytesize" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81a18687293a1546b67c246452202bbbf143d239cb43494cc163da14979082da" + [[package]] name = "df" version = "0.1.0" dependencies = [ "ascii_table", + "bytesize", "libc", "procinfo", + "xflags", ] [[package]] @@ -32,6 +42,15 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf51a729ecf40266a2368ad335a5fdde43471f545a967109cd62146ecf8b66ff" +[[package]] +name = "proc-macro2" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +dependencies = [ + "unicode-xid", +] + [[package]] name = "procinfo" version = "0.4.2" @@ -67,3 +86,27 @@ name = "semver-parser" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "unicode-xid" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" + +[[package]] +name = "xflags" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ad6ce6a0b7224130015b4ebac796478ac04e0079f5d222a690efea06a9208a" +dependencies = [ + "xflags-macros", +] + +[[package]] +name = "xflags-macros" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8037d3ca14996158b03c0fa905d0834906ef0fc7044df72c1f5ff690e5e62c9" +dependencies = [ + "proc-macro2", +] diff --git a/Cargo.toml b/Cargo.toml index a073de5..c864fb1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,5 +9,7 @@ edition = "2018" [dependencies] ascii_table = { git = "https://gitlab.com/arnekeller/ascii-table.git", rev = "7fffb5d93b8c63283fc1359ee3c6dbfcf12ed90b" } +bytesize = "1.0.1" libc = "0.2.91" procinfo = "0.4.2" +xflags = "0.2.1" diff --git a/src/flags.rs b/src/flags.rs new file mode 100644 index 0000000..342138e --- /dev/null +++ b/src/flags.rs @@ -0,0 +1,29 @@ +xflags::xflags! { + src "./src/flags.rs" + + cmd df + { + optional -h, --human-readable + } +} + +// generated start +// The following code is generated by `xflags` macro. +// Run `env UPDATE_XFLAGS=1 cargo build` to regenerate. +#[derive(Debug)] +pub struct Df { + pub human_readable: bool, +} + +impl Df { + pub const HELP: &'static str = Self::HELP_; + + pub fn from_env() -> xflags::Result { + Self::from_env_() + } + + pub fn from_vec(args: Vec) -> xflags::Result { + Self::from_vec_(args) + } +} +// generated end diff --git a/src/main.rs b/src/main.rs index 5c45697..7550856 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,4 @@ +use bytesize::ByteSize; use libc::{c_char, statvfs64, strerror_r}; use procinfo::pid::mountinfo_self; use ascii_table::{Align, AsciiTable, Column}; @@ -5,10 +6,14 @@ use ascii_table::{Align, AsciiTable, Column}; use std::{array::IntoIter, ffi::CString, fs, mem::MaybeUninit}; use std::os::unix::ffi::OsStrExt; +mod flags; + const IGNORED_FS: &'static [&'static str] = &["proc", "sysfs", "securityfs", "bpf", "cgroup", "cgroup2", "fusectl", "efivarfs", "debugfs"]; -const IGNORED_FS2: &'static [(&'static str, &'static str)] = &[];//("fuse", "portal")]; +const IGNORED_FS2: &'static [(&'static str, &'static str)] = &[("fuse", "portal")]; fn main() { + let flags = flags::Df::from_env(); + let mut rows = Vec::new(); let mut devices = Vec::new(); for mount in mountinfo_self().unwrap() { @@ -57,14 +62,16 @@ fn main() { }, _ => mount.fs_type.0 }; - rows.push((typ, data.f_blocks, data.f_bfree, mount.mount_point)); + rows.push((typ, data.f_blocks, data.f_bfree, mount.mount_point, data.f_frsize)); } let mut ascii_table = AsciiTable::default(); ascii_table.draw_lines = false; + let human_readable = flags.as_ref().map(|x| x.human_readable).unwrap_or(false); + for (i, &(header, align)) in [ ("Filesystem", Align::Left), - ("Blocks", Align::Right), + (if !human_readable { "Blocks" } else { "Size" }, Align::Right), ("Used", Align::Right), ("Free", Align::Right), ("Use%", Align::Right), @@ -77,12 +84,27 @@ fn main() { } ascii_table.print(rows.into_iter().map( - |(typ, blocks, free, path)| IntoIter::new( + |(typ, blocks, free, path, frsize)| IntoIter::new( [ typ, - blocks.to_string(), - (blocks-free).to_string(), - free.to_string(), + if human_readable { + let bytes = blocks * frsize; + ByteSize(bytes).to_string_as(true) + } else { + blocks.to_string() + }, + if human_readable { + let bytes = (blocks-free) * frsize; + ByteSize(bytes).to_string_as(true) + } else { + (blocks-free).to_string() + }, + if human_readable { + let bytes = free * frsize; + ByteSize(bytes).to_string_as(true) + } else { + free.to_string() + }, format!("{:.0}%", ((blocks-free) as f64 * 100.0 / blocks as f64).ceil()), path.display().to_string() ]