Implemented long output and inode output for rbls
This commit is contained in:
parent
bf36e496c4
commit
792536d683
3 changed files with 249 additions and 13 deletions
176
Cargo.lock
generated
176
Cargo.lock
generated
|
@ -2,6 +2,21 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "android-tzdata"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
|
||||
|
||||
[[package]]
|
||||
name = "android_system_properties"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.13"
|
||||
|
@ -50,6 +65,44 @@ dependencies = [
|
|||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d32a725bc159af97c3e629873bb9f88fb8cf8a4867175f76dc987815ea07c83b"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
|
||||
dependencies = [
|
||||
"android-tzdata",
|
||||
"iana-time-zone",
|
||||
"js-sys",
|
||||
"num-traits",
|
||||
"wasm-bindgen",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.4"
|
||||
|
@ -109,6 +162,12 @@ dependencies = [
|
|||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
|
||||
|
||||
[[package]]
|
||||
name = "encode_unicode"
|
||||
version = "0.3.6"
|
||||
|
@ -121,6 +180,38 @@ version = "0.5.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"core-foundation-sys",
|
||||
"iana-time-zone-haiku",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"windows-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone-haiku"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
|
@ -133,6 +224,27 @@ version = "0.2.153"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.81"
|
||||
|
@ -155,6 +267,7 @@ dependencies = [
|
|||
name = "rbutils"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"clap",
|
||||
"console",
|
||||
]
|
||||
|
@ -194,6 +307,69 @@ version = "0.2.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
|
|
|
@ -6,5 +6,6 @@ edition = "2021"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
chrono = "0.4.38"
|
||||
clap = { version = "4.5.4", features = ["derive"] }
|
||||
console = "0.15.8"
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use clap::Parser;
|
||||
use chrono::{Local, TimeZone};
|
||||
use std::io::{self, ErrorKind::*};
|
||||
use std::fs::{self, DirEntry, Metadata};
|
||||
use std::os::unix::fs::{FileTypeExt, MetadataExt};
|
||||
|
||||
// TODO: implement more options (-l, -i, etc.)
|
||||
fn main() {
|
||||
let cli = Cli::parse();
|
||||
let mut non_dirs = Vec::<FileInfo>::new();
|
||||
|
@ -28,12 +29,17 @@ fn main() {
|
|||
};
|
||||
dirs.push(DirInfo::new(file_name, file_infos));
|
||||
}
|
||||
|
||||
let (dirs_len, non_dirs_len) = (dirs.len(), non_dirs.len());
|
||||
|
||||
if !non_dirs.is_empty() {
|
||||
let non_dirs_filtered = transform_file_infos(non_dirs, &cli);
|
||||
let non_dirs_output = format_output(non_dirs_filtered, &cli);
|
||||
println!("{}", non_dirs_output);
|
||||
}
|
||||
let dirs_output = if dirs.len() > 1 {
|
||||
|
||||
if dirs.is_empty() { return; }
|
||||
let dirs_output = if dirs_len + non_dirs_len > 1 {
|
||||
dirs.into_iter()
|
||||
.map(|dir| {
|
||||
let files_filtered = transform_file_infos(dir.file_infos, &cli);
|
||||
|
@ -46,6 +52,8 @@ fn main() {
|
|||
let files_filtered = transform_file_infos(dir.file_infos, &cli);
|
||||
format_output(files_filtered, &cli)
|
||||
};
|
||||
|
||||
if non_dirs_len > 0 { println!(); }
|
||||
println!("{}", dirs_output);
|
||||
}
|
||||
|
||||
|
@ -76,28 +84,79 @@ fn transform_file_infos(file_infos: Vec<FileInfo>, options: &Cli) -> Vec<String>
|
|||
filtered_file_infos.sort_by(|fi1, fi2| fi1.name.to_lowercase().cmp(&fi2.name.to_lowercase()));
|
||||
return filtered_file_infos.into_iter()
|
||||
.map(|file_info| {
|
||||
let mut file_name = file_info.name;
|
||||
if file_info.metadata.is_dir() { file_name.push('/') }
|
||||
return file_name;
|
||||
|
||||
return format_file_info(file_info, options);
|
||||
})
|
||||
.collect();
|
||||
}
|
||||
|
||||
fn format_output(file_names: Vec<String>, options: &Cli) -> String {
|
||||
let term = console::Term::stdout();
|
||||
if term.is_term() { return format_tabular(file_names, options, term.size().1); }
|
||||
else { return file_names.join(" "); }
|
||||
fn format_file_info(file_info: FileInfo, options: &Cli) -> String {
|
||||
let mut entry = String::new();
|
||||
if options.inode {
|
||||
entry.push_str(&file_info.metadata.ino().to_string());
|
||||
entry.push(' ');
|
||||
}
|
||||
if options.long {
|
||||
entry.push_str(&long_format(&file_info))
|
||||
} else {
|
||||
entry.push_str(&file_info.name)
|
||||
}
|
||||
if file_info.metadata.is_dir() { entry.push('/') }
|
||||
return entry;
|
||||
}
|
||||
|
||||
fn format_tabular(mut file_names: Vec<String>, options: &Cli, term_width: u16) -> String {
|
||||
let max_file_name_len = file_names.iter().map(|n| n.len()).max().unwrap();
|
||||
fn long_format(file_info: &FileInfo) -> String {
|
||||
format!("{} {} {} {} {} {} {}", permissions_str(&file_info.metadata), file_info.metadata.nlink(),
|
||||
file_info.metadata.uid(), file_info.metadata.gid(), file_info.metadata.size(),
|
||||
modified_str(&file_info.metadata), file_info.name)
|
||||
}
|
||||
|
||||
fn modified_str(metadata: &Metadata) -> String {
|
||||
let date_time = Local.timestamp_opt(metadata.mtime(), 0).unwrap();
|
||||
return date_time.format("%b %d %H:%M").to_string();
|
||||
}
|
||||
|
||||
fn permissions_str(metadata: &Metadata) -> String {
|
||||
let ftype = metadata.file_type();
|
||||
let mut result = String::with_capacity(10);
|
||||
result.push(
|
||||
if ftype.is_dir() { 'd' }
|
||||
else if ftype.is_symlink() { 'l' }
|
||||
else if ftype.is_block_device() { 'b' }
|
||||
else if ftype.is_char_device() { 'c' }
|
||||
else if ftype.is_fifo() { 'p' }
|
||||
else if ftype.is_socket() { 's' }
|
||||
else { '-' }
|
||||
);
|
||||
|
||||
let permission_chars: Vec<char> = vec!['r', 'w', 'x'];
|
||||
let permissions = metadata.mode();
|
||||
for i in 0..9 {
|
||||
let bit = permissions >> (8 - i) & 1;
|
||||
result.push(
|
||||
if bit > 0 { permission_chars[i % 3] }
|
||||
else { '-' }
|
||||
);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
fn format_output(file_names: Vec<String>, options: &Cli) -> String {
|
||||
let term = console::Term::stdout();
|
||||
if term.is_term() && !options.long { return format_tabular(file_names, term.size().1); }
|
||||
return file_names.join("\n");
|
||||
}
|
||||
|
||||
fn format_tabular(mut entries: Vec<String>, term_width: u16) -> String {
|
||||
if entries.is_empty() { return String::new(); }
|
||||
let max_file_name_len = entries.iter().map(|n| n.len()).max().unwrap();
|
||||
let elem_width = max_file_name_len + 2;
|
||||
let row_elems_amount = (term_width as usize / elem_width).max(1);
|
||||
for (i, name) in file_names.iter_mut().enumerate() {
|
||||
for (i, name) in entries.iter_mut().enumerate() {
|
||||
name.push_str(&" ".repeat(max_file_name_len - name.len() + 2));
|
||||
if (i + 1) % row_elems_amount == 0 { name.push('\n'); }
|
||||
}
|
||||
return file_names.join("").trim_end().to_string();
|
||||
return entries.join("").trim_end().to_string();
|
||||
}
|
||||
|
||||
struct DirInfo {
|
||||
|
|
Loading…
Reference in a new issue