From 1438cfd12589794bab22dfd3da417a6eb9db83c2 Mon Sep 17 00:00:00 2001 From: Guilleag01 Date: Wed, 15 Nov 2023 22:13:08 +0100 Subject: [PATCH] sort option --- src/element.rs | 6 +++++- src/main.rs | 8 ++++++-- src/out/list.rs | 22 +++++++++++++++++----- src/utils.rs | 36 ++++++++++++++++++++++++++++++++---- 4 files changed, 60 insertions(+), 12 deletions(-) diff --git a/src/element.rs b/src/element.rs index 7a29049..4ecd3b2 100644 --- a/src/element.rs +++ b/src/element.rs @@ -78,7 +78,11 @@ impl Element { file_type: t, name, perms: Some(metadata.permissions()), - size: metadata.len(), + size: if t == TypeOfFile::Dir { + 0 + } else { + metadata.len() + }, creation: metadata.created().unwrap_or(SystemTime::now()), } } diff --git a/src/main.rs b/src/main.rs index 0f3b47f..a7e2e1b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ use clap::Parser; use lsplus::{ out::{default::default, list::list}, - utils::get_elements_from_path, + utils::{get_elements_from_path, SortBy}, }; // Needs to be defined in main @@ -21,6 +21,10 @@ pub struct Args { #[arg(short, long, default_value_t = 0)] recursive: usize, + /// Sort elements by parameter + #[arg(short, long, default_value_t = SortBy::NONE)] + sort: SortBy, + /// Path of the directory to list #[arg(default_value_t = String::from("."))] path: String, @@ -32,7 +36,7 @@ fn main() { let elements = get_elements_from_path(args.path, args.all); if args.list { - list(elements, args.recursive); + list(elements, args.recursive, args.sort); } else { default(elements); } diff --git a/src/out/list.rs b/src/out/list.rs index 82fc7b9..d40c543 100644 --- a/src/out/list.rs +++ b/src/out/list.rs @@ -1,9 +1,10 @@ use crate::element::{Element, TypeOfFile}; use crate::utils::{ - get_elements_from_path, get_size_string, get_string_length, pad_string, system_time_to_string, + get_elements_from_path, get_size_string, get_string_length, pad_string, sort_elements, + system_time_to_string, SortBy, }; -pub fn list(elements: Vec, recursive_limit: usize) { +pub fn list(mut elements: Vec, recursive_limit: usize, sort_by: SortBy) { // ╭──────────────╼ File name ╾──────────────┬─╼ Size ╾─┬──╼ Creation ╾──╮ // │ some_example_file │ 420.69 G │ 01-01-70 00:00 │ // ╰─────────────────────────────────────────┴──────────┴────────────────╯ @@ -17,7 +18,14 @@ pub fn list(elements: Vec, recursive_limit: usize) { .min(width - 31); print_header(name_length); - let num_elements = print_elements(&elements, name_length, recursive_limit, 0, &Vec::new()); + let num_elements = print_elements( + &mut elements, + name_length, + recursive_limit, + 0, + &Vec::new(), + &sort_by, + ); print_footer(num_elements, name_length); } @@ -34,12 +42,15 @@ fn print_header(name_length: usize) { } fn print_elements( - elements: &Vec, + elements: &mut Vec, name_length: usize, recursive_limit: usize, current_depth: usize, is_last_element: &[bool], + sort_by: &SortBy, ) -> usize { + sort_elements(elements, sort_by); + let mut num_elements = elements.len(); let mut new_is_last_element = is_last_element.to_owned(); @@ -101,11 +112,12 @@ fn print_elements( let dir_path = e.get_path_string(); new_is_last_element.push(i == elements.len() - 1); num_elements += print_elements( - &get_elements_from_path(dir_path, true), + &mut get_elements_from_path(dir_path, true), name_length, recursive_limit, current_depth + 1, &new_is_last_element, + sort_by, ); new_is_last_element.pop(); } diff --git a/src/utils.rs b/src/utils.rs index 9bb4b79..48e8126 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,10 +1,28 @@ -use std::fs; -use std::time::SystemTime; - +use crate::element::Element; use chrono::offset::Utc; use chrono::DateTime; +use clap::ValueEnum; +use std::{cmp::Reverse, fmt::Display, fs, time::SystemTime}; -use crate::element::Element; +#[derive(ValueEnum, Clone, Debug)] +pub enum SortBy { + NONE, + NAME, + SIZE, + CREATION, +} + +impl Display for SortBy { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let text = match self { + Self::NONE => "none", + Self::NAME => "name", + Self::SIZE => "size", + Self::CREATION => "creation", + }; + write!(f, "{}", text) + } +} #[inline] pub fn get_elements_from_path(path: String, all: bool) -> Vec { @@ -55,6 +73,15 @@ pub fn system_time_to_string(system_time: SystemTime) -> String { datetime.format("%d-%m-%y %H:%M").to_string() } +pub fn sort_elements(elements: &mut Vec, sort_by: &SortBy) { + match sort_by { + SortBy::NONE => (), + SortBy::NAME => elements.sort_unstable_by_key(|a| a.get_name()), + SortBy::SIZE => elements.sort_unstable_by_key(|e| Reverse(e.get_size())), + SortBy::CREATION => elements.sort_unstable_by_key(|e| Reverse(e.get_creation())), + } +} + // ALL ICONS MUST BE FOLLOWED BY A SPACE pub fn get_icon_file_type<'a>(filename: String) -> &'a str { let extension = filename.split('.').last().unwrap(); //.collect::>()[1..].join("."); @@ -86,6 +113,7 @@ pub fn get_icon_file_type<'a>(filename: String) -> &'a str { "rs" => " ", "js" => " ", "sh" => " ", + "db" => "󰆼 ", "c" => " ", _ => "󰈔 ", }