output formatting and printing performance improvements

This commit is contained in:
sreedevk
2025-07-19 01:26:46 +00:00
parent 130a8f99ba
commit 711eb36fb9
2 changed files with 30 additions and 70 deletions

View File

@@ -2,20 +2,17 @@ use crate::{fileinfo::FileInfo, params::Params};
use anyhow::Result;
use chrono::{DateTime, Utc};
use dashmap::DashMap;
use indicatif::{ParallelProgressIterator, ProgressBar, ProgressFinish, ProgressStyle};
use pathdiff::diff_paths;
use prettytable::{format, row, Row, Table};
use rayon::prelude::*;
use std::{borrow::Cow, path::PathBuf, sync::Arc, time::Duration};
use std::{path::PathBuf, sync::Arc};
const YELLOW: &str = "\x1b[33m";
const RESET: &str = "\x1b[0m";
pub struct Formatter;
impl Formatter {
pub fn human_path(
file: &FileInfo,
app_args: &Params,
min_path_length: usize,
) -> Result<String> {
let base_directory: PathBuf = app_args.get_directory()?;
pub fn human_path(file: &FileInfo, aargs: &Params, min_path_length: usize) -> Result<String> {
let base_directory: PathBuf = aargs.get_directory()?;
let relative_path = diff_paths(&file.path, base_directory).unwrap_or_default();
let formatted_path = format!(
@@ -36,70 +33,33 @@ impl Formatter {
Ok(modified_time.format("%Y-%m-%d %H:%M:%S").to_string())
}
pub fn hash_hex(hash: &u128) -> Box<str> {
format!("{:32x}", hash).into_boxed_str()
}
pub fn print(raw: Arc<DashMap<u128, Vec<FileInfo>>>, max_path_len: u64, aargs: &Params) {
print!("\n\n\n"); // spacing
pub fn gen_sub_tbl(items: Vec<FileInfo>, app_args: &Params, max_path_len: u64) -> Table {
let mut inner_table = Table::new();
inner_table.set_format(*format::consts::FORMAT_NO_BORDER_LINE_SEPARATOR);
items.iter().for_each(|file| {
inner_table.add_row(row![
Self::human_path(file, app_args, max_path_len as usize).unwrap_or_default(),
Self::human_filesize(file).unwrap_or_default(),
Self::human_mtime(file).unwrap_or_default()
]);
});
inner_table
}
pub fn generate_table(
raw: Arc<DashMap<u128, Vec<FileInfo>>>,
mpath_len: u64,
args: &Params,
) -> Result<Table> {
let progress_bar = match args.progress {
true => ProgressBar::new_spinner(),
false => ProgressBar::hidden(),
};
let progress_style = ProgressStyle::with_template("[{elapsed_precise}] {pos:>7} {msg}")?;
progress_bar.set_style(progress_style);
progress_bar.enable_steady_tick(Duration::from_millis(50));
progress_bar.set_message("generating output");
let rows = raw
.par_iter_mut()
.progress_with(progress_bar)
.with_finish(ProgressFinish::WithMessage(Cow::from("output generated")))
.filter(|i| i.value().len() > 1)
.map(|i| {
row![
Self::hash_hex(i.key()),
Self::gen_sub_tbl(i.value().to_vec(), args, mpath_len)
]
})
.collect::<Vec<Row>>();
let mut output_table = Table::new();
output_table.set_titles(row!["hash", "duplicates"]);
output_table.extend(rows);
Ok(output_table)
}
pub fn print(
raw: Arc<DashMap<u128, Vec<FileInfo>>>,
max_path_len: u64,
app_args: &Params,
) -> Result<()> {
if raw.is_empty() {
println!("\n\nNo duplicates found matching your search criteria.\n");
return Ok(());
println!("No duplicates found matching your search criteria.");
return;
}
let output_table = Self::generate_table(raw, max_path_len, app_args)?;
output_table.printstd();
raw.par_iter().for_each(|sref| {
let mut ostring = format!("{}{:32x}{}\n", YELLOW, sref.key(), RESET);
let subfields = sref
.value()
.par_iter()
.map(|finfo| {
format!(
"├─ {}\t{}\t{}\n",
Self::human_path(finfo, aargs, max_path_len as usize)
.expect("path formatting failed."),
Self::human_filesize(finfo).expect("filesize formatting failed."),
Self::human_mtime(finfo).expect("modified time formatting failed.")
)
})
.collect::<String>();
Ok(())
ostring.push_str(&subfields);
println!("{ostring}");
});
}
}

View File

@@ -24,7 +24,7 @@ fn main() -> Result<()> {
server.hw_duplicate_set,
server.max_file_path_len.load(Ordering::Acquire),
&app_args,
)?;
);
}
true => {
Interactive::init(server.hw_duplicate_set, &app_args)?;