use crate::database::File; use chrono::offset::Utc; use chrono::DateTime; use colored::Colorize; use humansize::{format_size, DECIMAL}; use std::{collections::HashMap, fs}; use crate::params::Params; fn format_path(path: &String, opts: &Params) -> String { let display_path = path.replace(&opts.get_directory().unwrap(), ""); let text_vec = display_path.chars().collect::>(); let display_range = if text_vec.len() > 32 { text_vec[(display_path.len() - 32)..].into_iter().collect::() } else { display_path }; format!("...{}", display_range) } fn file_size(path: &String) -> String { let mdata = fs::metadata(path).unwrap(); let formatted_size = format_size(mdata.len(), DECIMAL); format!("{}", formatted_size) } fn modified_time(path: &String) -> String { let mdata = fs::metadata(path).unwrap(); let modified_time: DateTime = mdata.modified().unwrap().into(); modified_time.format("%Y-%m-%d %H:%M:%S").to_string() } fn print_divider() { println!("-------------------+-------------------------------------+------------------+----------------------------------+"); } pub fn print(duplicates: Vec, opts: &Params) { print_divider(); println!( "| {0: <16} | {1: <35} | {2: <16} | {3: <32} |", "hash", "filename", "size", "updated_at" ); print_divider(); let mut dup_index: HashMap> = HashMap::new(); duplicates.into_iter().for_each(|file| { dup_index .entry(file.hash.clone()) .and_modify(|value| value.push(file.clone())) .or_insert(vec![file]); }); dup_index.into_iter().for_each(|(_, group)| { group.into_iter().for_each(|file| { println!( "| {0: <16} | {1: <35} | {2: <16} | {3: <32} |", file.hash.red(), format_path(&file.path, opts).yellow(), file_size(&file.path).blue(), modified_time(&file.path).blue() ); }); print_divider(); }); }