use std::{cmp, path};
use std::collections::HashMap;
use std::path::PathBuf;
use chrono::*;
#[cfg(target_family = "windows")]
use regex::Captures;
use termcolor::{Color, ColorSpec, WriteColor};
use crate::config::{Config, EntryKind};
use crate::error::MyResult;
use crate::finder::{File, Total};
use crate::regex;
const MODE_WIDTH: usize = 10; const TIME_WIDTH: usize = 20; const PAD_WIDTH: usize = 2;
#[derive(PartialEq)]
enum DirStyle {
None,
Separator,
Brackets,
}
enum FileStyle {
None,
Exec,
Link,
}
#[allow(dead_code)]
pub struct Printer<'a, W: WriteColor> {
config: &'a Config,
writer: W,
counter: HashMap<PathBuf, usize>,
dir_color: ColorSpec,
exec_color: ColorSpec,
link_color: ColorSpec,
git_bash: bool,
separator: char,
separator_str: String,
}
impl<'a, W: WriteColor> Printer<'a, W> {
pub fn new(config: &Config, writer: W, git_bash: bool) -> Printer<W> {
let counter = HashMap::new();
let dir_color = create_color(Color::Blue, true);
let exec_color = create_color(Color::Green, true);
let link_color = create_color(Color::Cyan, true);
let separator = if git_bash { '/' } else { path::MAIN_SEPARATOR };
let separator_str = separator.to_string();
Printer {
config,
writer,
counter,
dir_color,
exec_color,
link_color,
git_bash,
separator,
separator_str,
}
}
pub fn print_files<Tz: TimeZone>(
&mut self,
files: &Vec<File>,
total: &Total,
zone: &Tz,
) -> MyResult<()> {
if self.config.show_indent {
self.count_parents(files);
}
if self.config.only_path {
for file in files {
self.print_path(file)?;
if self.config.null_path {
write!(self.writer, "\x00")?;
} else {
writeln!(self.writer)?;
}
}
} else {
let size_width = if self.config.show_total {
measure_size(total.total_size)
} else {
measure_size(total.max_size)
};
if self.config.filter_recent.is_some() {
self.print_start(total, zone, size_width)?;
}
for file in files {
self.print_file(file, total, zone, size_width)?;
}
if self.config.show_total {
self.print_total(total, size_width)?;
}
}
return Ok(());
}
fn print_start<Tz: TimeZone>(
&mut self,
total: &Total,
zone: &Tz,
size_width: usize,
) -> MyResult<()> {
if let Some(start_time) = total.start_time {
self.print_text("Start", MODE_WIDTH + PAD_WIDTH + size_width + PAD_WIDTH)?;
self.print_time(start_time, zone, false)?;
writeln!(self.writer)?;
self.print_hyphens(MODE_WIDTH + PAD_WIDTH + size_width + PAD_WIDTH + TIME_WIDTH)?;
}
return Ok(());
}
fn print_file<Tz: TimeZone>(
&mut self,
file: &File,
total: &Total,
zone: &Tz,
size_width: usize,
) -> MyResult<()> {
self.print_mode(file.file_type, file.file_mode)?;
self.print_size(file.file_size, size_width)?;
self.print_time(file.file_time, zone, true)?;
self.print_ext(&file.file_ext, total.ext_width)?;
self.print_path(file)?;
writeln!(self.writer)?;
return Ok(());
}
fn print_total(
&mut self,
total: &Total,
size_width: usize,
) -> MyResult<()> {
let files = if total.num_files == 1 { "file" } else { "files" };
let dirs = if total.num_dirs == 1 { "directory" } else { "directories" };
self.print_hyphens(MODE_WIDTH + PAD_WIDTH + size_width + PAD_WIDTH + TIME_WIDTH)?;
self.print_text("Total", MODE_WIDTH + PAD_WIDTH)?;
self.print_size(total.total_size, size_width)?;
self.print_spaces(TIME_WIDTH + PAD_WIDTH)?;
if total.ext_width > 0 {
self.print_spaces(total.ext_width + PAD_WIDTH)?;
}
writeln!(self.writer, "{num_files} {files} {num_dirs} {dirs}", num_files = total.num_files, num_dirs = total.num_dirs)?;
return Ok(());
}
fn print_mode(
&mut self,
file_type: EntryKind,
file_mode: u32,
) -> MyResult<()> {
match file_type {
EntryKind::File => write!(self.writer, "-")?,
EntryKind::Dir => write!(self.writer, "d")?,
EntryKind::Link => write!(self.writer, "l")?,
EntryKind::Other => write!(self.writer, "?")?,
};
for shift in [6, 3, 0] {
let file_mode = file_mode >> shift;
if (file_mode & 4) != 0 {
write!(self.writer, "r")?;
} else {
write!(self.writer, "-")?;
}
if (file_mode & 2) != 0 {
write!(self.writer, "w")?;
} else {
write!(self.writer, "-")?;
}
if (file_mode & 1) != 0 {
write!(self.writer, "x")?;
} else {
write!(self.writer, "-")?;
}
}
self.print_spaces(PAD_WIDTH)?;
return Ok(());
}
fn print_size(
&mut self,
file_size: u64,
size_width: usize,
) -> MyResult<()> {
self.print_thousand(file_size, size_width)?;
self.print_spaces(PAD_WIDTH)?;
return Ok(());
}
fn print_thousand(
&mut self,
file_size: u64,
size_width: usize,
) -> MyResult<()> {
if file_size < 1000 {
write!(self.writer, "{0:1$}", file_size, size_width)?;
} else {
self.print_thousand(file_size / 1000, cmp::max(size_width, 4) - 4)?;
write!(self.writer, ",{0:03}", file_size % 1000)?;
}
return Ok(());
}
fn print_time<Tz: TimeZone>(
&mut self,
file_time: DateTime<Utc>,
zone: &Tz,
padding: bool,
) -> MyResult<()> {
let file_time = file_time.with_timezone(zone);
let day = file_time.day();
let month = convert_month(file_time.month());
let year = file_time.year();
let hour = file_time.hour();
let minute = file_time.minute();
let second = file_time.second();
write!(self.writer, "{day:02}-{month}-{year:04} {hour:02}:{minute:02}:{second:02}")?;
if padding {
self.print_spaces(PAD_WIDTH)?;
}
return Ok(());
}
fn print_ext(
&mut self,
file_ext: &str,
ext_width: usize,
) -> MyResult<()> {
if ext_width > 0 {
write!(self.writer, "{0:1$}", file_ext, ext_width)?;
self.print_spaces(PAD_WIDTH)?;
}
return Ok(());
}
fn print_path(
&mut self,
file: &File,
) -> MyResult<()> {
if self.config.show_indent {
let prefix = self.create_prefix(file);
write!(self.writer, "{prefix}")?;
if file.file_type == EntryKind::Dir {
let file_dir = file.select_name_for_indent().unwrap_or("");
self.print_dir(file_dir, DirStyle::None)?;
} else {
let file_style = file_style(file);
self.print_name(&file.file_name, file_style)?;
}
self.print_link(&file.link_path)?;
} else {
let file_dir = file.select_dir(self.config.abs_path).to_str().unwrap_or("");
let file_name = &file.file_name;
let file_style = file_style(file);
if self.config.order_name {
self.print_name(file_name, file_style)?;
self.print_dir(file_dir, DirStyle::Brackets)?;
self.print_link(&file.link_path)?;
} else {
self.print_dir(file_dir, DirStyle::Separator)?;
self.print_name(file_name, file_style)?;
if !self.config.escape_path && !self.config.null_path {
self.print_link(&file.link_path)?;
}
}
}
return Ok(());
}
fn print_dir(
&mut self,
file_dir: &str,
dir_style: DirStyle,
) -> MyResult<()> {
if !file_dir.is_empty() && file_dir != "." {
if dir_style == DirStyle::Brackets {
write!(self.writer, " (")?;
}
self.writer.set_color(&self.dir_color)?;
self.escape_dir(file_dir)?;
if dir_style == DirStyle::Separator && !file_dir.ends_with(path::MAIN_SEPARATOR) {
write!(self.writer, "{}", self.separator)?;
}
self.writer.reset()?;
if dir_style == DirStyle::Brackets {
write!(self.writer, ")")?;
}
}
return Ok(());
}
#[cfg(target_family = "windows")]
fn escape_dir(
&mut self,
file_dir: &str,
) -> MyResult<()> {
if self.git_bash {
let drive_regex = regex!(r#"^([A-Z]):(.*)$"#);
let file_dir = file_dir.replace(path::MAIN_SEPARATOR, &self.separator_str);
let file_dir = drive_regex.replace(&file_dir, |caps: &Captures| {
format!("{}{}{}", self.separator, &caps[1].to_lowercase(), &caps[2])
});
if self.config.escape_path {
let escape_regex = regex!(r#"([\s"'])"#);
let file_dir = escape_regex.replace_all(&file_dir, "\\$1");
write!(self.writer, "{file_dir}")?;
} else {
write!(self.writer, "{file_dir}")?;
}
} else {
write!(self.writer, "{file_dir}")?;
}
return Ok(());
}
#[cfg(not(target_family = "windows"))]
fn escape_dir(
&mut self,
file_dir: &str,
) -> MyResult<()> {
if self.config.escape_path {
let escape_regex = regex!(r#"([\s"'\\])"#);
let file_dir = escape_regex.replace_all(file_dir, "\\$1");
write!(self.writer, "{file_dir}")?;
} else {
write!(self.writer, "{file_dir}")?;
}
return Ok(());
}
fn print_name(
&mut self,
file_name: &str,
file_style: FileStyle,
) -> MyResult<()> {
if !file_name.is_empty() {
match file_style {
FileStyle::None => {
self.escape_name(file_name)?;
},
FileStyle::Exec => {
self.writer.set_color(&self.exec_color)?;
self.escape_name(file_name)?;
self.writer.reset()?;
},
FileStyle::Link => {
self.writer.set_color(&self.link_color)?;
self.escape_name(file_name)?;
self.writer.reset()?;
},
}
}
return Ok(());
}
#[cfg(target_family = "windows")]
fn escape_name(
&mut self,
file_name: &str,
) -> MyResult<()> {
if self.config.escape_path && self.git_bash {
let escape_regex = regex!(r#"([\s"'])"#);
let file_name = escape_regex.replace_all(file_name, "\\$1");
write!(self.writer, "{file_name}")?;
} else {
write!(self.writer, "{file_name}")?;
}
return Ok(());
}
#[cfg(not(target_family = "windows"))]
fn escape_name(
&mut self,
file_name: &str,
) -> MyResult<()> {
if self.config.escape_path {
let escape_regex = regex!(r#"([\s"'\\])"#);
let file_name = escape_regex.replace_all(file_name, "\\$1");
write!(self.writer, "{file_name}")?;
} else {
write!(self.writer, "{file_name}")?;
}
return Ok(());
}
fn print_link(
&mut self,
link_path: &Option<PathBuf>,
) -> MyResult<()> {
if let Some(link_path) = link_path {
if let Some(link_dir) = link_path.parent().and_then(|x| x.to_str()) {
if let Some(link_name) = link_path.file_name().and_then(|x| x.to_str()) {
write!(self.writer, " -> ")?;
self.print_dir(link_dir, DirStyle::Separator)?;
self.print_name(link_name, FileStyle::None)?;
}
}
}
return Ok(());
}
fn count_parents(&mut self, files: &Vec<File>) {
for file in files {
if file.file_depth > 1 {
if let Some(parent) = file.select_parent_for_indent() {
let parent = PathBuf::from(parent);
let entry = self.counter.entry(parent).or_insert(0);
*entry += 1;
}
}
}
}
fn create_prefix(&mut self, file: &File) -> String {
let mut prefix = vec![];
if let Some(parent) = file.select_parent_for_indent() {
let mut path = PathBuf::from(parent);
if let Some(count) = self.counter.get_mut(&path) {
*count -= 1;
if *count > 0 {
prefix.push(" +- ");
} else {
prefix.push(" \\- ");
}
}
while let Some(parent) = path.parent() {
path = PathBuf::from(parent);
if let Some(count) = self.counter.get(&path) {
if *count > 0 {
prefix.push(" | ");
} else {
prefix.push(" ");
}
}
}
}
prefix.reverse();
return prefix.join("");
}
fn print_text(&mut self, text: &str, width: usize) -> MyResult<()> {
write!(self.writer, "{0:<1$}", text, width)?;
return Ok(());
}
fn print_spaces(&mut self, width: usize) -> MyResult<()> {
write!(self.writer, "{0:<1$}", "", width)?;
return Ok(());
}
fn print_hyphens(&mut self, width: usize) -> MyResult<()> {
writeln!(self.writer, "{0:-<1$}", "", width)?;
return Ok(());
}
}
fn measure_size(size: u64) -> usize {
if size < 1000 {
3
} else {
measure_size(size / 1000) + 4
}
}
fn convert_month(month: u32) -> &'static str {
match month {
1 => "Jan",
2 => "Feb",
3 => "Mar",
4 => "Apr",
5 => "May",
6 => "Jun",
7 => "Jul",
8 => "Aug",
9 => "Sep",
10 => "Oct",
11 => "Nov",
12 => "Dec",
_ => "???",
}
}
fn file_style(file: &File) -> FileStyle {
if file.file_type == EntryKind::File && (file.file_mode & 0o100) != 0 {
FileStyle::Exec
} else if file.file_type == EntryKind::Link {
FileStyle::Link
} else {
FileStyle::None
}
}
fn create_color(color: Color, bold: bool) -> ColorSpec {
let mut color_spec = ColorSpec::new();
color_spec.set_fg(Some(color));
color_spec.set_bold(bold);
return color_spec;
}
#[cfg(test)]
mod tests {
use std::io;
use std::io::Write;
use std::path::PathBuf;
use path_clean::PathClean;
use pretty_assertions::assert_eq;
use crate::config::{Recent, RecentKind};
use super::*;
#[test]
fn test_prints_type() {
assert_eq!("---------- ", wrap_mode(EntryKind::File, 0o000));
assert_eq!("d--------- ", wrap_mode(EntryKind::Dir, 0o000));
assert_eq!("l--------- ", wrap_mode(EntryKind::Link, 0o000));
assert_eq!("?--------- ", wrap_mode(EntryKind::Other, 0o000));
}
#[test]
fn test_prints_mode() {
assert_eq!("---------- ", wrap_mode(EntryKind::File, 0o000));
assert_eq!("-r-------- ", wrap_mode(EntryKind::File, 0o400));
assert_eq!("--w------- ", wrap_mode(EntryKind::File, 0o200));
assert_eq!("---x------ ", wrap_mode(EntryKind::File, 0o100));
assert_eq!("----r----- ", wrap_mode(EntryKind::File, 0o040));
assert_eq!("-----w---- ", wrap_mode(EntryKind::File, 0o020));
assert_eq!("------x--- ", wrap_mode(EntryKind::File, 0o010));
assert_eq!("-------r-- ", wrap_mode(EntryKind::File, 0o004));
assert_eq!("--------w- ", wrap_mode(EntryKind::File, 0o002));
assert_eq!("---------x ", wrap_mode(EntryKind::File, 0o001));
assert_eq!("-rwxrwxrwx ", wrap_mode(EntryKind::File, 0o777));
}
#[test]
fn test_measures_size() {
assert_eq!(3, measure_size(0));
assert_eq!(3, measure_size(999));
assert_eq!(7, measure_size(1000));
assert_eq!(7, measure_size(999999));
assert_eq!(11, measure_size(1000000));
assert_eq!(11, measure_size(999999999));
}
#[test]
fn test_prints_unpadded_size() {
assert_eq!("0 ", wrap_size(0, 0));
assert_eq!("9 ", wrap_size(9, 0));
assert_eq!("10 ", wrap_size(10, 0));
assert_eq!("99 ", wrap_size(99, 0));
assert_eq!("100 ", wrap_size(100, 0));
assert_eq!("999 ", wrap_size(999, 0));
assert_eq!("1,000 ", wrap_size(1000, 0));
assert_eq!("9,999 ", wrap_size(9999, 0));
assert_eq!("10,000 ", wrap_size(10000, 0));
assert_eq!("99,999 ", wrap_size(99999, 0));
assert_eq!("100,000 ", wrap_size(100000, 0));
assert_eq!("999,999 ", wrap_size(999999, 0));
assert_eq!("1,000,000 ", wrap_size(1000000, 0));
assert_eq!("9,999,999 ", wrap_size(9999999, 0));
assert_eq!("10,000,000 ", wrap_size(10000000, 0));
assert_eq!("99,999,999 ", wrap_size(99999999, 0));
assert_eq!("100,000,000 ", wrap_size(100000000, 0));
assert_eq!("999,999,999 ", wrap_size(999999999, 0));
}
#[test]
fn test_prints_padded_size() {
assert_eq!(" 0 ", wrap_size(0, 11));
assert_eq!(" 9 ", wrap_size(9, 11));
assert_eq!(" 10 ", wrap_size(10, 11));
assert_eq!(" 99 ", wrap_size(99, 11));
assert_eq!(" 100 ", wrap_size(100, 11));
assert_eq!(" 999 ", wrap_size(999, 11));
assert_eq!(" 1,000 ", wrap_size(1000, 11));
assert_eq!(" 9,999 ", wrap_size(9999, 11));
assert_eq!(" 10,000 ", wrap_size(10000, 11));
assert_eq!(" 99,999 ", wrap_size(99999, 11));
assert_eq!(" 100,000 ", wrap_size(100000, 11));
assert_eq!(" 999,999 ", wrap_size(999999, 11));
assert_eq!(" 1,000,000 ", wrap_size(1000000, 11));
assert_eq!(" 9,999,999 ", wrap_size(9999999, 11));
assert_eq!(" 10,000,000 ", wrap_size(10000000, 11));
assert_eq!(" 99,999,999 ", wrap_size(99999999, 11));
assert_eq!("100,000,000 ", wrap_size(100000000, 11));
assert_eq!("999,999,999 ", wrap_size(999999999, 11));
}
#[test]
fn test_prints_time() {
assert_eq!("31-Jan-2024 00:00:00 ", wrap_time(2024, 1, 31, 0, 0, 0));
assert_eq!("29-Feb-2024 02:05:15 ", wrap_time(2024, 2, 29, 2, 5, 15));
assert_eq!("31-Mar-2024 04:10:30 ", wrap_time(2024, 3, 31, 4, 10, 30));
assert_eq!("30-Apr-2024 06:15:45 ", wrap_time(2024, 4, 30, 6, 15, 45));
assert_eq!("31-May-2024 08:20:00 ", wrap_time(2024, 5, 31, 8, 20, 0));
assert_eq!("30-Jun-2024 10:25:15 ", wrap_time(2024, 6, 30, 10, 25, 15));
assert_eq!("31-Jul-2024 12:30:30 ", wrap_time(2024, 7, 31, 12, 30, 30));
assert_eq!("31-Aug-2024 14:35:45 ", wrap_time(2024, 8, 31, 14, 35, 45));
assert_eq!("30-Sep-2024 16:40:00 ", wrap_time(2024, 9, 30, 16, 40, 0));
assert_eq!("31-Oct-2024 18:45:15 ", wrap_time(2024, 10, 31, 18, 45, 15));
assert_eq!("30-Nov-2024 20:50:30 ", wrap_time(2024, 11, 30, 20, 50, 30));
assert_eq!("31-Dec-2024 22:55:45 ", wrap_time(2024, 12, 31, 22, 55, 45));
}
#[test]
fn test_prints_unpadded_ext() {
assert_eq!("", wrap_ext("", 0));
assert_eq!("", wrap_ext(".txt", 0));
assert_eq!("", wrap_ext(".extension", 0));
}
#[test]
fn test_prints_padded_ext() {
assert_eq!(" ", wrap_ext("", 6));
assert_eq!(".txt ", wrap_ext(".txt", 6));
assert_eq!(".extension ", wrap_ext(".extension", 6));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_relative_paths_on_windows() {
let expected = "\
-rwxr--r-- 10 01-Jan-2023 00:00:00 .sh [LtGreen]find.sh[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files\\[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files\\colours\\[Reset]
-rwxr--r-- 20 01-Feb-2023 00:00:00 .sh [LtBlue]files\\colours\\[Reset][LtGreen]paint.sh[Reset]
-rw-r--r-- 30 01-Mar-2023 00:00:00 .txt [LtBlue]files\\colours\\[Reset]blue.txt
-rw-r--r-- 40 01-Apr-2023 00:00:00 .txt [LtBlue]files\\colours\\[Reset]green.txt
-rw-r--r-- 50 01-May-2023 00:00:00 .txt [LtBlue]files\\colours\\[Reset]red.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files\\numbers\\[Reset]
-rwxr--r-- 60 01-Jun-2023 00:00:00 .sh [LtBlue]files\\numbers\\[Reset][LtGreen]count.sh[Reset]
lrw-r--r-- 999 01-Jul-2023 00:00:00 .txt [LtBlue]files\\numbers\\[Reset][LtCyan]googolplex.txt[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset]googolplex.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files\\numbers\\one two\\[Reset]
-rw-r--r-- 70 01-Aug-2023 00:00:00 .txt [LtBlue]files\\numbers\\one two\\[Reset]\"three\" 'four'.txt
";
let (files, total) = create_files("D:", "/root", "");
let mut config = Config::default();
config.abs_path = false;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_relative_paths_on_git_bash() {
let expected = "\
-rwxr--r-- 10 01-Jan-2023 00:00:00 .sh [LtGreen]find.sh[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/colours/[Reset]
-rwxr--r-- 20 01-Feb-2023 00:00:00 .sh [LtBlue]files/colours/[Reset][LtGreen]paint.sh[Reset]
-rw-r--r-- 30 01-Mar-2023 00:00:00 .txt [LtBlue]files/colours/[Reset]blue.txt
-rw-r--r-- 40 01-Apr-2023 00:00:00 .txt [LtBlue]files/colours/[Reset]green.txt
-rw-r--r-- 50 01-May-2023 00:00:00 .txt [LtBlue]files/colours/[Reset]red.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/numbers/[Reset]
-rwxr--r-- 60 01-Jun-2023 00:00:00 .sh [LtBlue]files/numbers/[Reset][LtGreen]count.sh[Reset]
lrw-r--r-- 999 01-Jul-2023 00:00:00 .txt [LtBlue]files/numbers/[Reset][LtCyan]googolplex.txt[Reset] -> [LtBlue]/d/etc/numbers/[Reset]googolplex.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/numbers/one two/[Reset]
-rw-r--r-- 70 01-Aug-2023 00:00:00 .txt [LtBlue]files/numbers/one two/[Reset]\"three\" 'four'.txt
";
let (files, total) = create_files("D:", "/root", "");
let mut config = Config::default();
config.abs_path = false;
assert_eq!(expected, wrap_files(&config, true, &files, &total));
}
#[test]
#[cfg(not(target_family = "windows"))]
fn test_prints_relative_paths_on_linux() {
let expected = "\
-rwxr--r-- 10 01-Jan-2023 00:00:00 .sh [LtGreen]find.sh[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/colours/[Reset]
-rwxr--r-- 20 01-Feb-2023 00:00:00 .sh [LtBlue]files/colours/[Reset][LtGreen]paint.sh[Reset]
-rw-r--r-- 30 01-Mar-2023 00:00:00 .txt [LtBlue]files/colours/[Reset]blue.txt
-rw-r--r-- 40 01-Apr-2023 00:00:00 .txt [LtBlue]files/colours/[Reset]green.txt
-rw-r--r-- 50 01-May-2023 00:00:00 .txt [LtBlue]files/colours/[Reset]red.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/numbers/[Reset]
-rwxr--r-- 60 01-Jun-2023 00:00:00 .sh [LtBlue]files/numbers/[Reset][LtGreen]count.sh[Reset]
lrw-r--r-- 999 01-Jul-2023 00:00:00 .txt [LtBlue]files/numbers/[Reset][LtCyan]googolplex.txt[Reset] -> [LtBlue]/etc/numbers/[Reset]googolplex.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/numbers/one two/[Reset]
-rw-r--r-- 70 01-Aug-2023 00:00:00 .txt [LtBlue]files/numbers/one two/[Reset]\"three\" 'four'.txt
";
let (files, total) = create_files("", "/root", "");
let mut config = Config::default();
config.abs_path = false;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_absolute_paths_on_windows() {
let expected = "\
-rwxr--r-- 10 01-Jan-2023 00:00:00 .sh [LtBlue]D:\\root\\[Reset][LtGreen]find.sh[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]D:\\root\\files\\[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]D:\\root\\files\\colours\\[Reset]
-rwxr--r-- 20 01-Feb-2023 00:00:00 .sh [LtBlue]D:\\root\\files\\colours\\[Reset][LtGreen]paint.sh[Reset]
-rw-r--r-- 30 01-Mar-2023 00:00:00 .txt [LtBlue]D:\\root\\files\\colours\\[Reset]blue.txt
-rw-r--r-- 40 01-Apr-2023 00:00:00 .txt [LtBlue]D:\\root\\files\\colours\\[Reset]green.txt
-rw-r--r-- 50 01-May-2023 00:00:00 .txt [LtBlue]D:\\root\\files\\colours\\[Reset]red.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]D:\\root\\files\\numbers\\[Reset]
-rwxr--r-- 60 01-Jun-2023 00:00:00 .sh [LtBlue]D:\\root\\files\\numbers\\[Reset][LtGreen]count.sh[Reset]
lrw-r--r-- 999 01-Jul-2023 00:00:00 .txt [LtBlue]D:\\root\\files\\numbers\\[Reset][LtCyan]googolplex.txt[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset]googolplex.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]D:\\root\\files\\numbers\\one two\\[Reset]
-rw-r--r-- 70 01-Aug-2023 00:00:00 .txt [LtBlue]D:\\root\\files\\numbers\\one two\\[Reset]\"three\" 'four'.txt
";
let (files, total) = create_files("D:", "/root", "");
let mut config = Config::default();
config.abs_path = true;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_absolute_paths_on_git_bash() {
let expected = "\
-rwxr--r-- 10 01-Jan-2023 00:00:00 .sh [LtBlue]/d/root/[Reset][LtGreen]find.sh[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/d/root/files/[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/d/root/files/colours/[Reset]
-rwxr--r-- 20 01-Feb-2023 00:00:00 .sh [LtBlue]/d/root/files/colours/[Reset][LtGreen]paint.sh[Reset]
-rw-r--r-- 30 01-Mar-2023 00:00:00 .txt [LtBlue]/d/root/files/colours/[Reset]blue.txt
-rw-r--r-- 40 01-Apr-2023 00:00:00 .txt [LtBlue]/d/root/files/colours/[Reset]green.txt
-rw-r--r-- 50 01-May-2023 00:00:00 .txt [LtBlue]/d/root/files/colours/[Reset]red.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/d/root/files/numbers/[Reset]
-rwxr--r-- 60 01-Jun-2023 00:00:00 .sh [LtBlue]/d/root/files/numbers/[Reset][LtGreen]count.sh[Reset]
lrw-r--r-- 999 01-Jul-2023 00:00:00 .txt [LtBlue]/d/root/files/numbers/[Reset][LtCyan]googolplex.txt[Reset] -> [LtBlue]/d/etc/numbers/[Reset]googolplex.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/d/root/files/numbers/one two/[Reset]
-rw-r--r-- 70 01-Aug-2023 00:00:00 .txt [LtBlue]/d/root/files/numbers/one two/[Reset]\"three\" 'four'.txt
";
let (files, total) = create_files("D:", "/root", "");
let mut config = Config::default();
config.abs_path = true;
assert_eq!(expected, wrap_files(&config, true, &files, &total));
}
#[test]
#[cfg(not(target_family = "windows"))]
fn test_prints_absolute_paths_on_linux() {
let expected = "\
-rwxr--r-- 10 01-Jan-2023 00:00:00 .sh [LtBlue]/root/[Reset][LtGreen]find.sh[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/root/files/[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/root/files/colours/[Reset]
-rwxr--r-- 20 01-Feb-2023 00:00:00 .sh [LtBlue]/root/files/colours/[Reset][LtGreen]paint.sh[Reset]
-rw-r--r-- 30 01-Mar-2023 00:00:00 .txt [LtBlue]/root/files/colours/[Reset]blue.txt
-rw-r--r-- 40 01-Apr-2023 00:00:00 .txt [LtBlue]/root/files/colours/[Reset]green.txt
-rw-r--r-- 50 01-May-2023 00:00:00 .txt [LtBlue]/root/files/colours/[Reset]red.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/root/files/numbers/[Reset]
-rwxr--r-- 60 01-Jun-2023 00:00:00 .sh [LtBlue]/root/files/numbers/[Reset][LtGreen]count.sh[Reset]
lrw-r--r-- 999 01-Jul-2023 00:00:00 .txt [LtBlue]/root/files/numbers/[Reset][LtCyan]googolplex.txt[Reset] -> [LtBlue]/etc/numbers/[Reset]googolplex.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/root/files/numbers/one two/[Reset]
-rw-r--r-- 70 01-Aug-2023 00:00:00 .txt [LtBlue]/root/files/numbers/one two/[Reset]\"three\" 'four'.txt
";
let (files, total) = create_files("", "/root", "");
let mut config = Config::default();
config.abs_path = true;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_relative_paths_at_root_on_windows() {
let expected = "\
-rwxr--r-- 10 01-Jan-2023 00:00:00 .sh [LtGreen]find.sh[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files\\[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files\\colours\\[Reset]
-rwxr--r-- 20 01-Feb-2023 00:00:00 .sh [LtBlue]files\\colours\\[Reset][LtGreen]paint.sh[Reset]
-rw-r--r-- 30 01-Mar-2023 00:00:00 .txt [LtBlue]files\\colours\\[Reset]blue.txt
-rw-r--r-- 40 01-Apr-2023 00:00:00 .txt [LtBlue]files\\colours\\[Reset]green.txt
-rw-r--r-- 50 01-May-2023 00:00:00 .txt [LtBlue]files\\colours\\[Reset]red.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files\\numbers\\[Reset]
-rwxr--r-- 60 01-Jun-2023 00:00:00 .sh [LtBlue]files\\numbers\\[Reset][LtGreen]count.sh[Reset]
lrw-r--r-- 999 01-Jul-2023 00:00:00 .txt [LtBlue]files\\numbers\\[Reset][LtCyan]googolplex.txt[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset]googolplex.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files\\numbers\\one two\\[Reset]
-rw-r--r-- 70 01-Aug-2023 00:00:00 .txt [LtBlue]files\\numbers\\one two\\[Reset]\"three\" 'four'.txt
";
let (files, total) = create_files("D:", "/", "");
let mut config = Config::default();
config.abs_path = false;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_relative_paths_at_root_on_git_bash() {
let expected = "\
-rwxr--r-- 10 01-Jan-2023 00:00:00 .sh [LtGreen]find.sh[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/colours/[Reset]
-rwxr--r-- 20 01-Feb-2023 00:00:00 .sh [LtBlue]files/colours/[Reset][LtGreen]paint.sh[Reset]
-rw-r--r-- 30 01-Mar-2023 00:00:00 .txt [LtBlue]files/colours/[Reset]blue.txt
-rw-r--r-- 40 01-Apr-2023 00:00:00 .txt [LtBlue]files/colours/[Reset]green.txt
-rw-r--r-- 50 01-May-2023 00:00:00 .txt [LtBlue]files/colours/[Reset]red.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/numbers/[Reset]
-rwxr--r-- 60 01-Jun-2023 00:00:00 .sh [LtBlue]files/numbers/[Reset][LtGreen]count.sh[Reset]
lrw-r--r-- 999 01-Jul-2023 00:00:00 .txt [LtBlue]files/numbers/[Reset][LtCyan]googolplex.txt[Reset] -> [LtBlue]/d/etc/numbers/[Reset]googolplex.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/numbers/one two/[Reset]
-rw-r--r-- 70 01-Aug-2023 00:00:00 .txt [LtBlue]files/numbers/one two/[Reset]\"three\" 'four'.txt
";
let (files, total) = create_files("D:", "/", "");
let mut config = Config::default();
config.abs_path = false;
assert_eq!(expected, wrap_files(&config, true, &files, &total));
}
#[test]
#[cfg(not(target_family = "windows"))]
fn test_prints_relative_paths_at_root_on_linux() {
let expected = "\
-rwxr--r-- 10 01-Jan-2023 00:00:00 .sh [LtGreen]find.sh[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/colours/[Reset]
-rwxr--r-- 20 01-Feb-2023 00:00:00 .sh [LtBlue]files/colours/[Reset][LtGreen]paint.sh[Reset]
-rw-r--r-- 30 01-Mar-2023 00:00:00 .txt [LtBlue]files/colours/[Reset]blue.txt
-rw-r--r-- 40 01-Apr-2023 00:00:00 .txt [LtBlue]files/colours/[Reset]green.txt
-rw-r--r-- 50 01-May-2023 00:00:00 .txt [LtBlue]files/colours/[Reset]red.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/numbers/[Reset]
-rwxr--r-- 60 01-Jun-2023 00:00:00 .sh [LtBlue]files/numbers/[Reset][LtGreen]count.sh[Reset]
lrw-r--r-- 999 01-Jul-2023 00:00:00 .txt [LtBlue]files/numbers/[Reset][LtCyan]googolplex.txt[Reset] -> [LtBlue]/etc/numbers/[Reset]googolplex.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/numbers/one two/[Reset]
-rw-r--r-- 70 01-Aug-2023 00:00:00 .txt [LtBlue]files/numbers/one two/[Reset]\"three\" 'four'.txt
";
let (files, total) = create_files("", "/", "");
let mut config = Config::default();
config.abs_path = false;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_absolute_paths_at_root_on_windows() {
let expected = "\
-rwxr--r-- 10 01-Jan-2023 00:00:00 .sh [LtBlue]D:\\[Reset][LtGreen]find.sh[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]D:\\files\\[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]D:\\files\\colours\\[Reset]
-rwxr--r-- 20 01-Feb-2023 00:00:00 .sh [LtBlue]D:\\files\\colours\\[Reset][LtGreen]paint.sh[Reset]
-rw-r--r-- 30 01-Mar-2023 00:00:00 .txt [LtBlue]D:\\files\\colours\\[Reset]blue.txt
-rw-r--r-- 40 01-Apr-2023 00:00:00 .txt [LtBlue]D:\\files\\colours\\[Reset]green.txt
-rw-r--r-- 50 01-May-2023 00:00:00 .txt [LtBlue]D:\\files\\colours\\[Reset]red.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]D:\\files\\numbers\\[Reset]
-rwxr--r-- 60 01-Jun-2023 00:00:00 .sh [LtBlue]D:\\files\\numbers\\[Reset][LtGreen]count.sh[Reset]
lrw-r--r-- 999 01-Jul-2023 00:00:00 .txt [LtBlue]D:\\files\\numbers\\[Reset][LtCyan]googolplex.txt[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset]googolplex.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]D:\\files\\numbers\\one two\\[Reset]
-rw-r--r-- 70 01-Aug-2023 00:00:00 .txt [LtBlue]D:\\files\\numbers\\one two\\[Reset]\"three\" 'four'.txt
";
let (files, total) = create_files("D:", "/", "");
let mut config = Config::default();
config.abs_path = true;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_absolute_paths_at_root_on_git_bash() {
let expected = "\
-rwxr--r-- 10 01-Jan-2023 00:00:00 .sh [LtBlue]/d/[Reset][LtGreen]find.sh[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/d/files/[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/d/files/colours/[Reset]
-rwxr--r-- 20 01-Feb-2023 00:00:00 .sh [LtBlue]/d/files/colours/[Reset][LtGreen]paint.sh[Reset]
-rw-r--r-- 30 01-Mar-2023 00:00:00 .txt [LtBlue]/d/files/colours/[Reset]blue.txt
-rw-r--r-- 40 01-Apr-2023 00:00:00 .txt [LtBlue]/d/files/colours/[Reset]green.txt
-rw-r--r-- 50 01-May-2023 00:00:00 .txt [LtBlue]/d/files/colours/[Reset]red.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/d/files/numbers/[Reset]
-rwxr--r-- 60 01-Jun-2023 00:00:00 .sh [LtBlue]/d/files/numbers/[Reset][LtGreen]count.sh[Reset]
lrw-r--r-- 999 01-Jul-2023 00:00:00 .txt [LtBlue]/d/files/numbers/[Reset][LtCyan]googolplex.txt[Reset] -> [LtBlue]/d/etc/numbers/[Reset]googolplex.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/d/files/numbers/one two/[Reset]
-rw-r--r-- 70 01-Aug-2023 00:00:00 .txt [LtBlue]/d/files/numbers/one two/[Reset]\"three\" 'four'.txt
";
let (files, total) = create_files("D:", "/", "");
let mut config = Config::default();
config.abs_path = true;
assert_eq!(expected, wrap_files(&config, true, &files, &total));
}
#[test]
#[cfg(not(target_family = "windows"))]
fn test_prints_absolute_paths_at_root_on_linux() {
let expected = "\
-rwxr--r-- 10 01-Jan-2023 00:00:00 .sh [LtBlue]/[Reset][LtGreen]find.sh[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/files/[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/files/colours/[Reset]
-rwxr--r-- 20 01-Feb-2023 00:00:00 .sh [LtBlue]/files/colours/[Reset][LtGreen]paint.sh[Reset]
-rw-r--r-- 30 01-Mar-2023 00:00:00 .txt [LtBlue]/files/colours/[Reset]blue.txt
-rw-r--r-- 40 01-Apr-2023 00:00:00 .txt [LtBlue]/files/colours/[Reset]green.txt
-rw-r--r-- 50 01-May-2023 00:00:00 .txt [LtBlue]/files/colours/[Reset]red.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/files/numbers/[Reset]
-rwxr--r-- 60 01-Jun-2023 00:00:00 .sh [LtBlue]/files/numbers/[Reset][LtGreen]count.sh[Reset]
lrw-r--r-- 999 01-Jul-2023 00:00:00 .txt [LtBlue]/files/numbers/[Reset][LtCyan]googolplex.txt[Reset] -> [LtBlue]/etc/numbers/[Reset]googolplex.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/files/numbers/one two/[Reset]
-rw-r--r-- 70 01-Aug-2023 00:00:00 .txt [LtBlue]/files/numbers/one two/[Reset]\"three\" 'four'.txt
";
let (files, total) = create_files("", "/", "");
let mut config = Config::default();
config.abs_path = true;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_relative_paths_with_start_header_on_windows() {
let expected = "\
Start 01-Jan-2023 00:00:00
-------------------------------------
-rwxr--r-- 10 01-Jan-2023 00:00:00 .sh [LtGreen]find.sh[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files\\[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files\\colours\\[Reset]
-rwxr--r-- 20 01-Feb-2023 00:00:00 .sh [LtBlue]files\\colours\\[Reset][LtGreen]paint.sh[Reset]
-rw-r--r-- 30 01-Mar-2023 00:00:00 .txt [LtBlue]files\\colours\\[Reset]blue.txt
-rw-r--r-- 40 01-Apr-2023 00:00:00 .txt [LtBlue]files\\colours\\[Reset]green.txt
-rw-r--r-- 50 01-May-2023 00:00:00 .txt [LtBlue]files\\colours\\[Reset]red.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files\\numbers\\[Reset]
-rwxr--r-- 60 01-Jun-2023 00:00:00 .sh [LtBlue]files\\numbers\\[Reset][LtGreen]count.sh[Reset]
lrw-r--r-- 999 01-Jul-2023 00:00:00 .txt [LtBlue]files\\numbers\\[Reset][LtCyan]googolplex.txt[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset]googolplex.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files\\numbers\\one two\\[Reset]
-rw-r--r-- 70 01-Aug-2023 00:00:00 .txt [LtBlue]files\\numbers\\one two\\[Reset]\"three\" 'four'.txt
";
let (files, total) = create_files("D:", "/root", "");
let mut config = Config::default();
config.filter_recent = Some(Recent::new(RecentKind::Year, 1));
config.abs_path = false;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_relative_paths_with_start_header_on_git_bash() {
let expected = "\
Start 01-Jan-2023 00:00:00
-------------------------------------
-rwxr--r-- 10 01-Jan-2023 00:00:00 .sh [LtGreen]find.sh[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/colours/[Reset]
-rwxr--r-- 20 01-Feb-2023 00:00:00 .sh [LtBlue]files/colours/[Reset][LtGreen]paint.sh[Reset]
-rw-r--r-- 30 01-Mar-2023 00:00:00 .txt [LtBlue]files/colours/[Reset]blue.txt
-rw-r--r-- 40 01-Apr-2023 00:00:00 .txt [LtBlue]files/colours/[Reset]green.txt
-rw-r--r-- 50 01-May-2023 00:00:00 .txt [LtBlue]files/colours/[Reset]red.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/numbers/[Reset]
-rwxr--r-- 60 01-Jun-2023 00:00:00 .sh [LtBlue]files/numbers/[Reset][LtGreen]count.sh[Reset]
lrw-r--r-- 999 01-Jul-2023 00:00:00 .txt [LtBlue]files/numbers/[Reset][LtCyan]googolplex.txt[Reset] -> [LtBlue]/d/etc/numbers/[Reset]googolplex.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/numbers/one two/[Reset]
-rw-r--r-- 70 01-Aug-2023 00:00:00 .txt [LtBlue]files/numbers/one two/[Reset]\"three\" 'four'.txt
";
let (files, total) = create_files("D:", "/root", "");
let mut config = Config::default();
config.filter_recent = Some(Recent::new(RecentKind::Year, 1));
config.abs_path = false;
assert_eq!(expected, wrap_files(&config, true, &files, &total));
}
#[test]
#[cfg(not(target_family = "windows"))]
fn test_prints_relative_paths_with_start_header_on_linux() {
let expected = "\
Start 01-Jan-2023 00:00:00
-------------------------------------
-rwxr--r-- 10 01-Jan-2023 00:00:00 .sh [LtGreen]find.sh[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/colours/[Reset]
-rwxr--r-- 20 01-Feb-2023 00:00:00 .sh [LtBlue]files/colours/[Reset][LtGreen]paint.sh[Reset]
-rw-r--r-- 30 01-Mar-2023 00:00:00 .txt [LtBlue]files/colours/[Reset]blue.txt
-rw-r--r-- 40 01-Apr-2023 00:00:00 .txt [LtBlue]files/colours/[Reset]green.txt
-rw-r--r-- 50 01-May-2023 00:00:00 .txt [LtBlue]files/colours/[Reset]red.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/numbers/[Reset]
-rwxr--r-- 60 01-Jun-2023 00:00:00 .sh [LtBlue]files/numbers/[Reset][LtGreen]count.sh[Reset]
lrw-r--r-- 999 01-Jul-2023 00:00:00 .txt [LtBlue]files/numbers/[Reset][LtCyan]googolplex.txt[Reset] -> [LtBlue]/etc/numbers/[Reset]googolplex.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/numbers/one two/[Reset]
-rw-r--r-- 70 01-Aug-2023 00:00:00 .txt [LtBlue]files/numbers/one two/[Reset]\"three\" 'four'.txt
";
let (files, total) = create_files("", "/root", "");
let mut config = Config::default();
config.filter_recent = Some(Recent::new(RecentKind::Year, 1));
config.abs_path = false;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_absolute_paths_with_start_header_on_windows() {
let expected = "\
Start 01-Jan-2023 00:00:00
-------------------------------------
-rwxr--r-- 10 01-Jan-2023 00:00:00 .sh [LtBlue]D:\\root\\[Reset][LtGreen]find.sh[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]D:\\root\\files\\[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]D:\\root\\files\\colours\\[Reset]
-rwxr--r-- 20 01-Feb-2023 00:00:00 .sh [LtBlue]D:\\root\\files\\colours\\[Reset][LtGreen]paint.sh[Reset]
-rw-r--r-- 30 01-Mar-2023 00:00:00 .txt [LtBlue]D:\\root\\files\\colours\\[Reset]blue.txt
-rw-r--r-- 40 01-Apr-2023 00:00:00 .txt [LtBlue]D:\\root\\files\\colours\\[Reset]green.txt
-rw-r--r-- 50 01-May-2023 00:00:00 .txt [LtBlue]D:\\root\\files\\colours\\[Reset]red.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]D:\\root\\files\\numbers\\[Reset]
-rwxr--r-- 60 01-Jun-2023 00:00:00 .sh [LtBlue]D:\\root\\files\\numbers\\[Reset][LtGreen]count.sh[Reset]
lrw-r--r-- 999 01-Jul-2023 00:00:00 .txt [LtBlue]D:\\root\\files\\numbers\\[Reset][LtCyan]googolplex.txt[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset]googolplex.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]D:\\root\\files\\numbers\\one two\\[Reset]
-rw-r--r-- 70 01-Aug-2023 00:00:00 .txt [LtBlue]D:\\root\\files\\numbers\\one two\\[Reset]\"three\" 'four'.txt
";
let (files, total) = create_files("D:", "/root", "");
let mut config = Config::default();
config.filter_recent = Some(Recent::new(RecentKind::Year, 1));
config.abs_path = true;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_absolute_paths_with_start_header_on_git_bash() {
let expected = "\
Start 01-Jan-2023 00:00:00
-------------------------------------
-rwxr--r-- 10 01-Jan-2023 00:00:00 .sh [LtBlue]/d/root/[Reset][LtGreen]find.sh[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/d/root/files/[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/d/root/files/colours/[Reset]
-rwxr--r-- 20 01-Feb-2023 00:00:00 .sh [LtBlue]/d/root/files/colours/[Reset][LtGreen]paint.sh[Reset]
-rw-r--r-- 30 01-Mar-2023 00:00:00 .txt [LtBlue]/d/root/files/colours/[Reset]blue.txt
-rw-r--r-- 40 01-Apr-2023 00:00:00 .txt [LtBlue]/d/root/files/colours/[Reset]green.txt
-rw-r--r-- 50 01-May-2023 00:00:00 .txt [LtBlue]/d/root/files/colours/[Reset]red.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/d/root/files/numbers/[Reset]
-rwxr--r-- 60 01-Jun-2023 00:00:00 .sh [LtBlue]/d/root/files/numbers/[Reset][LtGreen]count.sh[Reset]
lrw-r--r-- 999 01-Jul-2023 00:00:00 .txt [LtBlue]/d/root/files/numbers/[Reset][LtCyan]googolplex.txt[Reset] -> [LtBlue]/d/etc/numbers/[Reset]googolplex.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/d/root/files/numbers/one two/[Reset]
-rw-r--r-- 70 01-Aug-2023 00:00:00 .txt [LtBlue]/d/root/files/numbers/one two/[Reset]\"three\" 'four'.txt
";
let (files, total) = create_files("D:", "/root", "");
let mut config = Config::default();
config.filter_recent = Some(Recent::new(RecentKind::Year, 1));
config.abs_path = true;
assert_eq!(expected, wrap_files(&config, true, &files, &total));
}
#[test]
#[cfg(not(target_family = "windows"))]
fn test_prints_absolute_paths_with_start_header_on_linux() {
let expected = "\
Start 01-Jan-2023 00:00:00
-------------------------------------
-rwxr--r-- 10 01-Jan-2023 00:00:00 .sh [LtBlue]/root/[Reset][LtGreen]find.sh[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/root/files/[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/root/files/colours/[Reset]
-rwxr--r-- 20 01-Feb-2023 00:00:00 .sh [LtBlue]/root/files/colours/[Reset][LtGreen]paint.sh[Reset]
-rw-r--r-- 30 01-Mar-2023 00:00:00 .txt [LtBlue]/root/files/colours/[Reset]blue.txt
-rw-r--r-- 40 01-Apr-2023 00:00:00 .txt [LtBlue]/root/files/colours/[Reset]green.txt
-rw-r--r-- 50 01-May-2023 00:00:00 .txt [LtBlue]/root/files/colours/[Reset]red.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/root/files/numbers/[Reset]
-rwxr--r-- 60 01-Jun-2023 00:00:00 .sh [LtBlue]/root/files/numbers/[Reset][LtGreen]count.sh[Reset]
lrw-r--r-- 999 01-Jul-2023 00:00:00 .txt [LtBlue]/root/files/numbers/[Reset][LtCyan]googolplex.txt[Reset] -> [LtBlue]/etc/numbers/[Reset]googolplex.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/root/files/numbers/one two/[Reset]
-rw-r--r-- 70 01-Aug-2023 00:00:00 .txt [LtBlue]/root/files/numbers/one two/[Reset]\"three\" 'four'.txt
";
let (files, total) = create_files("", "/root", "");
let mut config = Config::default();
config.filter_recent = Some(Recent::new(RecentKind::Year, 1));
config.abs_path = true;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_relative_paths_with_total_footer_on_windows() {
let expected = "\
-rwxr--r-- 10 01-Jan-2023 00:00:00 .sh [LtGreen]find.sh[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files\\[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files\\colours\\[Reset]
-rwxr--r-- 20 01-Feb-2023 00:00:00 .sh [LtBlue]files\\colours\\[Reset][LtGreen]paint.sh[Reset]
-rw-r--r-- 30 01-Mar-2023 00:00:00 .txt [LtBlue]files\\colours\\[Reset]blue.txt
-rw-r--r-- 40 01-Apr-2023 00:00:00 .txt [LtBlue]files\\colours\\[Reset]green.txt
-rw-r--r-- 50 01-May-2023 00:00:00 .txt [LtBlue]files\\colours\\[Reset]red.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files\\numbers\\[Reset]
-rwxr--r-- 60 01-Jun-2023 00:00:00 .sh [LtBlue]files\\numbers\\[Reset][LtGreen]count.sh[Reset]
lrw-r--r-- 999 01-Jul-2023 00:00:00 .txt [LtBlue]files\\numbers\\[Reset][LtCyan]googolplex.txt[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset]googolplex.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files\\numbers\\one two\\[Reset]
-rw-r--r-- 70 01-Aug-2023 00:00:00 .txt [LtBlue]files\\numbers\\one two\\[Reset]\"three\" 'four'.txt
-----------------------------------------
Total 1,279 8 files 4 directories
";
let (files, total) = create_files("D:", "/root", "");
let mut config = Config::default();
config.show_total = true;
config.abs_path = false;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_relative_paths_with_total_footer_on_git_bash() {
let expected = "\
-rwxr--r-- 10 01-Jan-2023 00:00:00 .sh [LtGreen]find.sh[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/colours/[Reset]
-rwxr--r-- 20 01-Feb-2023 00:00:00 .sh [LtBlue]files/colours/[Reset][LtGreen]paint.sh[Reset]
-rw-r--r-- 30 01-Mar-2023 00:00:00 .txt [LtBlue]files/colours/[Reset]blue.txt
-rw-r--r-- 40 01-Apr-2023 00:00:00 .txt [LtBlue]files/colours/[Reset]green.txt
-rw-r--r-- 50 01-May-2023 00:00:00 .txt [LtBlue]files/colours/[Reset]red.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/numbers/[Reset]
-rwxr--r-- 60 01-Jun-2023 00:00:00 .sh [LtBlue]files/numbers/[Reset][LtGreen]count.sh[Reset]
lrw-r--r-- 999 01-Jul-2023 00:00:00 .txt [LtBlue]files/numbers/[Reset][LtCyan]googolplex.txt[Reset] -> [LtBlue]/d/etc/numbers/[Reset]googolplex.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/numbers/one two/[Reset]
-rw-r--r-- 70 01-Aug-2023 00:00:00 .txt [LtBlue]files/numbers/one two/[Reset]\"three\" 'four'.txt
-----------------------------------------
Total 1,279 8 files 4 directories
";
let (files, total) = create_files("D:", "/root", "");
let mut config = Config::default();
config.show_total = true;
config.abs_path = false;
assert_eq!(expected, wrap_files(&config, true, &files, &total));
}
#[test]
#[cfg(not(target_family = "windows"))]
fn test_prints_relative_paths_with_total_footer_on_linux() {
let expected = "\
-rwxr--r-- 10 01-Jan-2023 00:00:00 .sh [LtGreen]find.sh[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/colours/[Reset]
-rwxr--r-- 20 01-Feb-2023 00:00:00 .sh [LtBlue]files/colours/[Reset][LtGreen]paint.sh[Reset]
-rw-r--r-- 30 01-Mar-2023 00:00:00 .txt [LtBlue]files/colours/[Reset]blue.txt
-rw-r--r-- 40 01-Apr-2023 00:00:00 .txt [LtBlue]files/colours/[Reset]green.txt
-rw-r--r-- 50 01-May-2023 00:00:00 .txt [LtBlue]files/colours/[Reset]red.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/numbers/[Reset]
-rwxr--r-- 60 01-Jun-2023 00:00:00 .sh [LtBlue]files/numbers/[Reset][LtGreen]count.sh[Reset]
lrw-r--r-- 999 01-Jul-2023 00:00:00 .txt [LtBlue]files/numbers/[Reset][LtCyan]googolplex.txt[Reset] -> [LtBlue]/etc/numbers/[Reset]googolplex.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files/numbers/one two/[Reset]
-rw-r--r-- 70 01-Aug-2023 00:00:00 .txt [LtBlue]files/numbers/one two/[Reset]\"three\" 'four'.txt
-----------------------------------------
Total 1,279 8 files 4 directories
";
let (files, total) = create_files("", "/root", "");
let mut config = Config::default();
config.show_total = true;
config.abs_path = false;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_absolute_paths_with_total_footer_on_windows() {
let expected = "\
-rwxr--r-- 10 01-Jan-2023 00:00:00 .sh [LtBlue]D:\\root\\[Reset][LtGreen]find.sh[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]D:\\root\\files\\[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]D:\\root\\files\\colours\\[Reset]
-rwxr--r-- 20 01-Feb-2023 00:00:00 .sh [LtBlue]D:\\root\\files\\colours\\[Reset][LtGreen]paint.sh[Reset]
-rw-r--r-- 30 01-Mar-2023 00:00:00 .txt [LtBlue]D:\\root\\files\\colours\\[Reset]blue.txt
-rw-r--r-- 40 01-Apr-2023 00:00:00 .txt [LtBlue]D:\\root\\files\\colours\\[Reset]green.txt
-rw-r--r-- 50 01-May-2023 00:00:00 .txt [LtBlue]D:\\root\\files\\colours\\[Reset]red.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]D:\\root\\files\\numbers\\[Reset]
-rwxr--r-- 60 01-Jun-2023 00:00:00 .sh [LtBlue]D:\\root\\files\\numbers\\[Reset][LtGreen]count.sh[Reset]
lrw-r--r-- 999 01-Jul-2023 00:00:00 .txt [LtBlue]D:\\root\\files\\numbers\\[Reset][LtCyan]googolplex.txt[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset]googolplex.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]D:\\root\\files\\numbers\\one two\\[Reset]
-rw-r--r-- 70 01-Aug-2023 00:00:00 .txt [LtBlue]D:\\root\\files\\numbers\\one two\\[Reset]\"three\" 'four'.txt
-----------------------------------------
Total 1,279 8 files 4 directories
";
let (files, total) = create_files("D:", "/root", "");
let mut config = Config::default();
config.show_total = true;
config.abs_path = true;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_absolute_paths_with_total_footer_on_git_bash() {
let expected = "\
-rwxr--r-- 10 01-Jan-2023 00:00:00 .sh [LtBlue]/d/root/[Reset][LtGreen]find.sh[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/d/root/files/[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/d/root/files/colours/[Reset]
-rwxr--r-- 20 01-Feb-2023 00:00:00 .sh [LtBlue]/d/root/files/colours/[Reset][LtGreen]paint.sh[Reset]
-rw-r--r-- 30 01-Mar-2023 00:00:00 .txt [LtBlue]/d/root/files/colours/[Reset]blue.txt
-rw-r--r-- 40 01-Apr-2023 00:00:00 .txt [LtBlue]/d/root/files/colours/[Reset]green.txt
-rw-r--r-- 50 01-May-2023 00:00:00 .txt [LtBlue]/d/root/files/colours/[Reset]red.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/d/root/files/numbers/[Reset]
-rwxr--r-- 60 01-Jun-2023 00:00:00 .sh [LtBlue]/d/root/files/numbers/[Reset][LtGreen]count.sh[Reset]
lrw-r--r-- 999 01-Jul-2023 00:00:00 .txt [LtBlue]/d/root/files/numbers/[Reset][LtCyan]googolplex.txt[Reset] -> [LtBlue]/d/etc/numbers/[Reset]googolplex.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/d/root/files/numbers/one two/[Reset]
-rw-r--r-- 70 01-Aug-2023 00:00:00 .txt [LtBlue]/d/root/files/numbers/one two/[Reset]\"three\" 'four'.txt
-----------------------------------------
Total 1,279 8 files 4 directories
";
let (files, total) = create_files("D:", "/root", "");
let mut config = Config::default();
config.show_total = true;
config.abs_path = true;
assert_eq!(expected, wrap_files(&config, true, &files, &total));
}
#[test]
#[cfg(not(target_family = "windows"))]
fn test_prints_absolute_paths_with_total_footer_on_linux() {
let expected = "\
-rwxr--r-- 10 01-Jan-2023 00:00:00 .sh [LtBlue]/root/[Reset][LtGreen]find.sh[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/root/files/[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/root/files/colours/[Reset]
-rwxr--r-- 20 01-Feb-2023 00:00:00 .sh [LtBlue]/root/files/colours/[Reset][LtGreen]paint.sh[Reset]
-rw-r--r-- 30 01-Mar-2023 00:00:00 .txt [LtBlue]/root/files/colours/[Reset]blue.txt
-rw-r--r-- 40 01-Apr-2023 00:00:00 .txt [LtBlue]/root/files/colours/[Reset]green.txt
-rw-r--r-- 50 01-May-2023 00:00:00 .txt [LtBlue]/root/files/colours/[Reset]red.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/root/files/numbers/[Reset]
-rwxr--r-- 60 01-Jun-2023 00:00:00 .sh [LtBlue]/root/files/numbers/[Reset][LtGreen]count.sh[Reset]
lrw-r--r-- 999 01-Jul-2023 00:00:00 .txt [LtBlue]/root/files/numbers/[Reset][LtCyan]googolplex.txt[Reset] -> [LtBlue]/etc/numbers/[Reset]googolplex.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]/root/files/numbers/one two/[Reset]
-rw-r--r-- 70 01-Aug-2023 00:00:00 .txt [LtBlue]/root/files/numbers/one two/[Reset]\"three\" 'four'.txt
-----------------------------------------
Total 1,279 8 files 4 directories
";
let (files, total) = create_files("", "/root", "");
let mut config = Config::default();
config.show_total = true;
config.abs_path = true;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_relative_paths_no_attributes_on_windows() {
let expected = "\
[LtGreen]find.sh[Reset]
[LtBlue]files\\[Reset]
[LtBlue]files\\colours\\[Reset]
[LtBlue]files\\colours\\[Reset][LtGreen]paint.sh[Reset]
[LtBlue]files\\colours\\[Reset]blue.txt
[LtBlue]files\\colours\\[Reset]green.txt
[LtBlue]files\\colours\\[Reset]red.txt
[LtBlue]files\\numbers\\[Reset]
[LtBlue]files\\numbers\\[Reset][LtGreen]count.sh[Reset]
[LtBlue]files\\numbers\\[Reset][LtCyan]googolplex.txt[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset]googolplex.txt
[LtBlue]files\\numbers\\one two\\[Reset]
[LtBlue]files\\numbers\\one two\\[Reset]\"three\" 'four'.txt
";
let (files, total) = create_files("D:", "/root", "");
let mut config = Config::default();
config.only_path = true;
config.abs_path = false;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_relative_paths_no_attributes_on_git_bash() {
let expected = "\
[LtGreen]find.sh[Reset]
[LtBlue]files/[Reset]
[LtBlue]files/colours/[Reset]
[LtBlue]files/colours/[Reset][LtGreen]paint.sh[Reset]
[LtBlue]files/colours/[Reset]blue.txt
[LtBlue]files/colours/[Reset]green.txt
[LtBlue]files/colours/[Reset]red.txt
[LtBlue]files/numbers/[Reset]
[LtBlue]files/numbers/[Reset][LtGreen]count.sh[Reset]
[LtBlue]files/numbers/[Reset][LtCyan]googolplex.txt[Reset] -> [LtBlue]/d/etc/numbers/[Reset]googolplex.txt
[LtBlue]files/numbers/one two/[Reset]
[LtBlue]files/numbers/one two/[Reset]\"three\" 'four'.txt
";
let (files, total) = create_files("D:", "/root", "");
let mut config = Config::default();
config.only_path = true;
config.abs_path = false;
assert_eq!(expected, wrap_files(&config, true, &files, &total));
}
#[test]
#[cfg(not(target_family = "windows"))]
fn test_prints_relative_paths_no_attributes_on_linux() {
let expected = "\
[LtGreen]find.sh[Reset]
[LtBlue]files/[Reset]
[LtBlue]files/colours/[Reset]
[LtBlue]files/colours/[Reset][LtGreen]paint.sh[Reset]
[LtBlue]files/colours/[Reset]blue.txt
[LtBlue]files/colours/[Reset]green.txt
[LtBlue]files/colours/[Reset]red.txt
[LtBlue]files/numbers/[Reset]
[LtBlue]files/numbers/[Reset][LtGreen]count.sh[Reset]
[LtBlue]files/numbers/[Reset][LtCyan]googolplex.txt[Reset] -> [LtBlue]/etc/numbers/[Reset]googolplex.txt
[LtBlue]files/numbers/one two/[Reset]
[LtBlue]files/numbers/one two/[Reset]\"three\" 'four'.txt
";
let (files, total) = create_files("", "/root", "");
let mut config = Config::default();
config.only_path = true;
config.abs_path = false;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_absolute_paths_no_attributes_on_windows() {
let expected = "\
[LtBlue]D:\\root\\[Reset][LtGreen]find.sh[Reset]
[LtBlue]D:\\root\\files\\[Reset]
[LtBlue]D:\\root\\files\\colours\\[Reset]
[LtBlue]D:\\root\\files\\colours\\[Reset][LtGreen]paint.sh[Reset]
[LtBlue]D:\\root\\files\\colours\\[Reset]blue.txt
[LtBlue]D:\\root\\files\\colours\\[Reset]green.txt
[LtBlue]D:\\root\\files\\colours\\[Reset]red.txt
[LtBlue]D:\\root\\files\\numbers\\[Reset]
[LtBlue]D:\\root\\files\\numbers\\[Reset][LtGreen]count.sh[Reset]
[LtBlue]D:\\root\\files\\numbers\\[Reset][LtCyan]googolplex.txt[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset]googolplex.txt
[LtBlue]D:\\root\\files\\numbers\\one two\\[Reset]
[LtBlue]D:\\root\\files\\numbers\\one two\\[Reset]\"three\" 'four'.txt
";
let (files, total) = create_files("D:", "/root", "");
let mut config = Config::default();
config.only_path = true;
config.abs_path = true;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_absolute_paths_no_attributes_on_git_bash() {
let expected = "\
[LtBlue]/d/root/[Reset][LtGreen]find.sh[Reset]
[LtBlue]/d/root/files/[Reset]
[LtBlue]/d/root/files/colours/[Reset]
[LtBlue]/d/root/files/colours/[Reset][LtGreen]paint.sh[Reset]
[LtBlue]/d/root/files/colours/[Reset]blue.txt
[LtBlue]/d/root/files/colours/[Reset]green.txt
[LtBlue]/d/root/files/colours/[Reset]red.txt
[LtBlue]/d/root/files/numbers/[Reset]
[LtBlue]/d/root/files/numbers/[Reset][LtGreen]count.sh[Reset]
[LtBlue]/d/root/files/numbers/[Reset][LtCyan]googolplex.txt[Reset] -> [LtBlue]/d/etc/numbers/[Reset]googolplex.txt
[LtBlue]/d/root/files/numbers/one two/[Reset]
[LtBlue]/d/root/files/numbers/one two/[Reset]\"three\" 'four'.txt
";
let (files, total) = create_files("D:", "/root", "");
let mut config = Config::default();
config.only_path = true;
config.abs_path = true;
assert_eq!(expected, wrap_files(&config, true, &files, &total));
}
#[test]
#[cfg(not(target_family = "windows"))]
fn test_prints_absolute_paths_no_attributes_on_linux() {
let expected = "\
[LtBlue]/root/[Reset][LtGreen]find.sh[Reset]
[LtBlue]/root/files/[Reset]
[LtBlue]/root/files/colours/[Reset]
[LtBlue]/root/files/colours/[Reset][LtGreen]paint.sh[Reset]
[LtBlue]/root/files/colours/[Reset]blue.txt
[LtBlue]/root/files/colours/[Reset]green.txt
[LtBlue]/root/files/colours/[Reset]red.txt
[LtBlue]/root/files/numbers/[Reset]
[LtBlue]/root/files/numbers/[Reset][LtGreen]count.sh[Reset]
[LtBlue]/root/files/numbers/[Reset][LtCyan]googolplex.txt[Reset] -> [LtBlue]/etc/numbers/[Reset]googolplex.txt
[LtBlue]/root/files/numbers/one two/[Reset]
[LtBlue]/root/files/numbers/one two/[Reset]\"three\" 'four'.txt
";
let (files, total) = create_files("", "/root", "");
let mut config = Config::default();
config.only_path = true;
config.abs_path = true;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_relative_paths_with_escaping_on_windows() {
let expected = "\
[LtGreen]find.sh[Reset]
[LtBlue]files\\[Reset]
[LtBlue]files\\colours\\[Reset]
[LtBlue]files\\colours\\[Reset][LtGreen]paint.sh[Reset]
[LtBlue]files\\colours\\[Reset]blue.txt
[LtBlue]files\\colours\\[Reset]green.txt
[LtBlue]files\\colours\\[Reset]red.txt
[LtBlue]files\\numbers\\[Reset]
[LtBlue]files\\numbers\\[Reset][LtGreen]count.sh[Reset]
[LtBlue]files\\numbers\\[Reset][LtCyan]googolplex.txt[Reset]
[LtBlue]files\\numbers\\one two\\[Reset]
[LtBlue]files\\numbers\\one two\\[Reset]\"three\" 'four'.txt
";
let (files, total) = create_files("D:", "/root", "");
let mut config = Config::default();
config.only_path = true;
config.escape_path = true;
config.abs_path = false;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_relative_paths_with_escaping_on_git_bash() {
let expected = "\
[LtGreen]find.sh[Reset]
[LtBlue]files/[Reset]
[LtBlue]files/colours/[Reset]
[LtBlue]files/colours/[Reset][LtGreen]paint.sh[Reset]
[LtBlue]files/colours/[Reset]blue.txt
[LtBlue]files/colours/[Reset]green.txt
[LtBlue]files/colours/[Reset]red.txt
[LtBlue]files/numbers/[Reset]
[LtBlue]files/numbers/[Reset][LtGreen]count.sh[Reset]
[LtBlue]files/numbers/[Reset][LtCyan]googolplex.txt[Reset]
[LtBlue]files/numbers/one\\ two/[Reset]
[LtBlue]files/numbers/one\\ two/[Reset]\\\"three\\\"\\ \\'four\\'.txt
";
let (files, total) = create_files("D:", "/root", "");
let mut config = Config::default();
config.only_path = true;
config.escape_path = true;
config.abs_path = false;
assert_eq!(expected, wrap_files(&config, true, &files, &total));
}
#[test]
#[cfg(not(target_family = "windows"))]
fn test_prints_relative_paths_with_escaping_on_linux() {
let expected = "\
[LtGreen]find.sh[Reset]
[LtBlue]files/[Reset]
[LtBlue]files/colours/[Reset]
[LtBlue]files/colours/[Reset][LtGreen]paint.sh[Reset]
[LtBlue]files/colours/[Reset]blue.txt
[LtBlue]files/colours/[Reset]green.txt
[LtBlue]files/colours/[Reset]red.txt
[LtBlue]files/numbers/[Reset]
[LtBlue]files/numbers/[Reset][LtGreen]count.sh[Reset]
[LtBlue]files/numbers/[Reset][LtCyan]googolplex.txt[Reset]
[LtBlue]files/numbers/one\\ two/[Reset]
[LtBlue]files/numbers/one\\ two/[Reset]\\\"three\\\"\\ \\'four\\'.txt
";
let (files, total) = create_files("", "/root", "");
let mut config = Config::default();
config.only_path = true;
config.escape_path = true;
config.abs_path = false;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_absolute_paths_with_escaping_on_windows() {
let expected = "\
[LtBlue]D:\\root\\[Reset][LtGreen]find.sh[Reset]
[LtBlue]D:\\root\\files\\[Reset]
[LtBlue]D:\\root\\files\\colours\\[Reset]
[LtBlue]D:\\root\\files\\colours\\[Reset][LtGreen]paint.sh[Reset]
[LtBlue]D:\\root\\files\\colours\\[Reset]blue.txt
[LtBlue]D:\\root\\files\\colours\\[Reset]green.txt
[LtBlue]D:\\root\\files\\colours\\[Reset]red.txt
[LtBlue]D:\\root\\files\\numbers\\[Reset]
[LtBlue]D:\\root\\files\\numbers\\[Reset][LtGreen]count.sh[Reset]
[LtBlue]D:\\root\\files\\numbers\\[Reset][LtCyan]googolplex.txt[Reset]
[LtBlue]D:\\root\\files\\numbers\\one two\\[Reset]
[LtBlue]D:\\root\\files\\numbers\\one two\\[Reset]\"three\" 'four'.txt
";
let (files, total) = create_files("D:", "/root", "");
let mut config = Config::default();
config.only_path = true;
config.escape_path = true;
config.abs_path = true;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_absolute_paths_with_escaping_on_git_bash() {
let expected = "\
[LtBlue]/d/root/[Reset][LtGreen]find.sh[Reset]
[LtBlue]/d/root/files/[Reset]
[LtBlue]/d/root/files/colours/[Reset]
[LtBlue]/d/root/files/colours/[Reset][LtGreen]paint.sh[Reset]
[LtBlue]/d/root/files/colours/[Reset]blue.txt
[LtBlue]/d/root/files/colours/[Reset]green.txt
[LtBlue]/d/root/files/colours/[Reset]red.txt
[LtBlue]/d/root/files/numbers/[Reset]
[LtBlue]/d/root/files/numbers/[Reset][LtGreen]count.sh[Reset]
[LtBlue]/d/root/files/numbers/[Reset][LtCyan]googolplex.txt[Reset]
[LtBlue]/d/root/files/numbers/one\\ two/[Reset]
[LtBlue]/d/root/files/numbers/one\\ two/[Reset]\\\"three\\\"\\ \\'four\\'.txt
";
let (files, total) = create_files("D:", "/root", "");
let mut config = Config::default();
config.only_path = true;
config.escape_path = true;
config.abs_path = true;
assert_eq!(expected, wrap_files(&config, true, &files, &total));
}
#[test]
#[cfg(not(target_family = "windows"))]
fn test_prints_absolute_paths_with_escaping_on_linux() {
let expected = "\
[LtBlue]/root/[Reset][LtGreen]find.sh[Reset]
[LtBlue]/root/files/[Reset]
[LtBlue]/root/files/colours/[Reset]
[LtBlue]/root/files/colours/[Reset][LtGreen]paint.sh[Reset]
[LtBlue]/root/files/colours/[Reset]blue.txt
[LtBlue]/root/files/colours/[Reset]green.txt
[LtBlue]/root/files/colours/[Reset]red.txt
[LtBlue]/root/files/numbers/[Reset]
[LtBlue]/root/files/numbers/[Reset][LtGreen]count.sh[Reset]
[LtBlue]/root/files/numbers/[Reset][LtCyan]googolplex.txt[Reset]
[LtBlue]/root/files/numbers/one\\ two/[Reset]
[LtBlue]/root/files/numbers/one\\ two/[Reset]\\\"three\\\"\\ \\'four\\'.txt
";
let (files, total) = create_files("", "/root", "");
let mut config = Config::default();
config.only_path = true;
config.escape_path = true;
config.abs_path = true;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_relative_paths_sorted_by_name_on_windows() {
let expected = "\
blue.txt ([LtBlue]files\\colours[Reset])
[LtGreen]count.sh[Reset] ([LtBlue]files\\numbers[Reset])
[LtGreen]find.sh[Reset]
[LtCyan]googolplex.txt[Reset] ([LtBlue]files\\numbers[Reset]) -> [LtBlue]D:\\etc\\numbers\\[Reset]googolplex.txt
green.txt ([LtBlue]files\\colours[Reset])
[LtGreen]paint.sh[Reset] ([LtBlue]files\\colours[Reset])
red.txt ([LtBlue]files\\colours[Reset])
\"three\" 'four'.txt ([LtBlue]files\\numbers\\one two[Reset])
";
let (files, total) = create_files_by_name("D:", "/root", "");
let mut config = Config::default();
config.only_path = true;
config.abs_path = false;
config.order_name = true;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_relative_paths_sorted_by_name_on_git_bash() {
let expected = "\
blue.txt ([LtBlue]files/colours[Reset])
[LtGreen]count.sh[Reset] ([LtBlue]files/numbers[Reset])
[LtGreen]find.sh[Reset]
[LtCyan]googolplex.txt[Reset] ([LtBlue]files/numbers[Reset]) -> [LtBlue]/d/etc/numbers/[Reset]googolplex.txt
green.txt ([LtBlue]files/colours[Reset])
[LtGreen]paint.sh[Reset] ([LtBlue]files/colours[Reset])
red.txt ([LtBlue]files/colours[Reset])
\"three\" 'four'.txt ([LtBlue]files/numbers/one two[Reset])
";
let (files, total) = create_files_by_name("D:", "/root", "");
let mut config = Config::default();
config.only_path = true;
config.abs_path = false;
config.order_name = true;
assert_eq!(expected, wrap_files(&config, true, &files, &total));
}
#[test]
#[cfg(not(target_family = "windows"))]
fn test_prints_relative_paths_sorted_by_name_on_linux() {
let expected = "\
blue.txt ([LtBlue]files/colours[Reset])
[LtGreen]count.sh[Reset] ([LtBlue]files/numbers[Reset])
[LtGreen]find.sh[Reset]
[LtCyan]googolplex.txt[Reset] ([LtBlue]files/numbers[Reset]) -> [LtBlue]/etc/numbers/[Reset]googolplex.txt
green.txt ([LtBlue]files/colours[Reset])
[LtGreen]paint.sh[Reset] ([LtBlue]files/colours[Reset])
red.txt ([LtBlue]files/colours[Reset])
\"three\" 'four'.txt ([LtBlue]files/numbers/one two[Reset])
";
let (files, total) = create_files_by_name("", "/root", "");
let mut config = Config::default();
config.only_path = true;
config.abs_path = false;
config.order_name = true;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_absolute_paths_sorted_by_name_on_windows() {
let expected = "\
blue.txt ([LtBlue]D:\\root\\files\\colours[Reset])
[LtGreen]count.sh[Reset] ([LtBlue]D:\\root\\files\\numbers[Reset])
[LtGreen]find.sh[Reset] ([LtBlue]D:\\root[Reset])
[LtCyan]googolplex.txt[Reset] ([LtBlue]D:\\root\\files\\numbers[Reset]) -> [LtBlue]D:\\etc\\numbers\\[Reset]googolplex.txt
green.txt ([LtBlue]D:\\root\\files\\colours[Reset])
[LtGreen]paint.sh[Reset] ([LtBlue]D:\\root\\files\\colours[Reset])
red.txt ([LtBlue]D:\\root\\files\\colours[Reset])
\"three\" 'four'.txt ([LtBlue]D:\\root\\files\\numbers\\one two[Reset])
";
let (files, total) = create_files_by_name("D:", "/root", "");
let mut config = Config::default();
config.only_path = true;
config.abs_path = true;
config.order_name = true;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_absolute_paths_sorted_by_name_on_git_bash() {
let expected = "\
blue.txt ([LtBlue]/d/root/files/colours[Reset])
[LtGreen]count.sh[Reset] ([LtBlue]/d/root/files/numbers[Reset])
[LtGreen]find.sh[Reset] ([LtBlue]/d/root[Reset])
[LtCyan]googolplex.txt[Reset] ([LtBlue]/d/root/files/numbers[Reset]) -> [LtBlue]/d/etc/numbers/[Reset]googolplex.txt
green.txt ([LtBlue]/d/root/files/colours[Reset])
[LtGreen]paint.sh[Reset] ([LtBlue]/d/root/files/colours[Reset])
red.txt ([LtBlue]/d/root/files/colours[Reset])
\"three\" 'four'.txt ([LtBlue]/d/root/files/numbers/one two[Reset])
";
let (files, total) = create_files_by_name("D:", "/root", "");
let mut config = Config::default();
config.only_path = true;
config.abs_path = true;
config.order_name = true;
assert_eq!(expected, wrap_files(&config, true, &files, &total));
}
#[test]
#[cfg(not(target_family = "windows"))]
fn test_prints_absolute_paths_sorted_by_name_on_linux() {
let expected = "\
blue.txt ([LtBlue]/root/files/colours[Reset])
[LtGreen]count.sh[Reset] ([LtBlue]/root/files/numbers[Reset])
[LtGreen]find.sh[Reset] ([LtBlue]/root[Reset])
[LtCyan]googolplex.txt[Reset] ([LtBlue]/root/files/numbers[Reset]) -> [LtBlue]/etc/numbers/[Reset]googolplex.txt
green.txt ([LtBlue]/root/files/colours[Reset])
[LtGreen]paint.sh[Reset] ([LtBlue]/root/files/colours[Reset])
red.txt ([LtBlue]/root/files/colours[Reset])
\"three\" 'four'.txt ([LtBlue]/root/files/numbers/one two[Reset])
";
let (files, total) = create_files_by_name("", "/root", "");
let mut config = Config::default();
config.only_path = true;
config.abs_path = true;
config.order_name = true;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_indented_paths_with_attributes_on_windows() {
let expected = "\
-rwxr--r-- 10 01-Jan-2023 00:00:00 .sh [LtGreen]find.sh[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 +- [LtBlue]colours[Reset]
-rwxr--r-- 20 01-Feb-2023 00:00:00 .sh | +- [LtGreen]paint.sh[Reset]
-rw-r--r-- 30 01-Mar-2023 00:00:00 .txt | +- blue.txt
-rw-r--r-- 40 01-Apr-2023 00:00:00 .txt | +- green.txt
-rw-r--r-- 50 01-May-2023 00:00:00 .txt | \\- red.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 \\- [LtBlue]numbers[Reset]
-rwxr--r-- 60 01-Jun-2023 00:00:00 .sh +- [LtGreen]count.sh[Reset]
lrw-r--r-- 999 01-Jul-2023 00:00:00 .txt +- [LtCyan]googolplex.txt[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset]googolplex.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 \\- [LtBlue]one two[Reset]
-rw-r--r-- 70 01-Aug-2023 00:00:00 .txt \\- \"three\" 'four'.txt
";
let (files, total) = create_files("D:", "/root", "../..");
let mut config = Config::default();
config.show_indent = true;
config.only_path = false;
config.abs_path = true;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_indented_paths_with_attributes_on_git_bash() {
let expected = "\
-rwxr--r-- 10 01-Jan-2023 00:00:00 .sh [LtGreen]find.sh[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 +- [LtBlue]colours[Reset]
-rwxr--r-- 20 01-Feb-2023 00:00:00 .sh | +- [LtGreen]paint.sh[Reset]
-rw-r--r-- 30 01-Mar-2023 00:00:00 .txt | +- blue.txt
-rw-r--r-- 40 01-Apr-2023 00:00:00 .txt | +- green.txt
-rw-r--r-- 50 01-May-2023 00:00:00 .txt | \\- red.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 \\- [LtBlue]numbers[Reset]
-rwxr--r-- 60 01-Jun-2023 00:00:00 .sh +- [LtGreen]count.sh[Reset]
lrw-r--r-- 999 01-Jul-2023 00:00:00 .txt +- [LtCyan]googolplex.txt[Reset] -> [LtBlue]/d/etc/numbers/[Reset]googolplex.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 \\- [LtBlue]one two[Reset]
-rw-r--r-- 70 01-Aug-2023 00:00:00 .txt \\- \"three\" 'four'.txt
";
let (files, total) = create_files("D:", "/root", "../..");
let mut config = Config::default();
config.show_indent = true;
config.only_path = false;
config.abs_path = true;
assert_eq!(expected, wrap_files(&config, true, &files, &total));
}
#[test]
#[cfg(not(target_family = "windows"))]
fn test_prints_indented_paths_with_attributes_on_linux() {
let expected = "\
-rwxr--r-- 10 01-Jan-2023 00:00:00 .sh [LtGreen]find.sh[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 [LtBlue]files[Reset]
drwxr-xr-x 0 01-Dec-2023 00:00:00 +- [LtBlue]colours[Reset]
-rwxr--r-- 20 01-Feb-2023 00:00:00 .sh | +- [LtGreen]paint.sh[Reset]
-rw-r--r-- 30 01-Mar-2023 00:00:00 .txt | +- blue.txt
-rw-r--r-- 40 01-Apr-2023 00:00:00 .txt | +- green.txt
-rw-r--r-- 50 01-May-2023 00:00:00 .txt | \\- red.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 \\- [LtBlue]numbers[Reset]
-rwxr--r-- 60 01-Jun-2023 00:00:00 .sh +- [LtGreen]count.sh[Reset]
lrw-r--r-- 999 01-Jul-2023 00:00:00 .txt +- [LtCyan]googolplex.txt[Reset] -> [LtBlue]/etc/numbers/[Reset]googolplex.txt
drwxr-xr-x 0 01-Dec-2023 00:00:00 \\- [LtBlue]one two[Reset]
-rw-r--r-- 70 01-Aug-2023 00:00:00 .txt \\- \"three\" 'four'.txt
";
let (files, total) = create_files("", "/root", "../..");
let mut config = Config::default();
config.show_indent = true;
config.only_path = false;
config.abs_path = true;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_indented_paths_no_attributes_on_windows() {
let expected = "\
[LtGreen]find.sh[Reset]
[LtBlue]files[Reset]
+- [LtBlue]colours[Reset]
| +- [LtGreen]paint.sh[Reset]
| +- blue.txt
| +- green.txt
| \\- red.txt
\\- [LtBlue]numbers[Reset]
+- [LtGreen]count.sh[Reset]
+- [LtCyan]googolplex.txt[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset]googolplex.txt
\\- [LtBlue]one two[Reset]
\\- \"three\" 'four'.txt
";
let (files, total) = create_files("D:", "/root", "../..");
let mut config = Config::default();
config.show_indent = true;
config.only_path = true;
config.abs_path = true;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
#[test]
#[cfg(target_family = "windows")]
fn test_prints_indented_paths_no_attributes_on_git_bash() {
let expected = "\
[LtGreen]find.sh[Reset]
[LtBlue]files[Reset]
+- [LtBlue]colours[Reset]
| +- [LtGreen]paint.sh[Reset]
| +- blue.txt
| +- green.txt
| \\- red.txt
\\- [LtBlue]numbers[Reset]
+- [LtGreen]count.sh[Reset]
+- [LtCyan]googolplex.txt[Reset] -> [LtBlue]/d/etc/numbers/[Reset]googolplex.txt
\\- [LtBlue]one two[Reset]
\\- \"three\" 'four'.txt
";
let (files, total) = create_files("D:", "/root", "../..");
let mut config = Config::default();
config.show_indent = true;
config.only_path = true;
config.abs_path = true;
assert_eq!(expected, wrap_files(&config, true, &files, &total));
}
#[test]
#[cfg(not(target_family = "windows"))]
fn test_prints_indented_paths_no_attributes_on_linux() {
let expected = "\
[LtGreen]find.sh[Reset]
[LtBlue]files[Reset]
+- [LtBlue]colours[Reset]
| +- [LtGreen]paint.sh[Reset]
| +- blue.txt
| +- green.txt
| \\- red.txt
\\- [LtBlue]numbers[Reset]
+- [LtGreen]count.sh[Reset]
+- [LtCyan]googolplex.txt[Reset] -> [LtBlue]/etc/numbers/[Reset]googolplex.txt
\\- [LtBlue]one two[Reset]
\\- \"three\" 'four'.txt
";
let (files, total) = create_files("", "/root", "../..");
let mut config = Config::default();
config.show_indent = true;
config.only_path = true;
config.abs_path = true;
assert_eq!(expected, wrap_files(&config, false, &files, &total));
}
fn wrap_mode(file_type: EntryKind, file_mode: u32) -> String {
let config = Config::default();
wrap_function(&config, false, |p| p.print_mode(file_type, file_mode))
}
fn wrap_size(file_size: u64, size_width: usize) -> String {
let config = Config::default();
wrap_function(&config, false, |p| p.print_size(file_size, size_width))
}
fn wrap_time(year: i32, month: u32, day: u32, hour: u32, minute: u32, second: u32) -> String {
let config = Config::default();
let time = Utc.with_ymd_and_hms(year, month, day, hour, minute, second).unwrap();
wrap_function(&config, false, |p| p.print_time(time, &Utc, true))
}
fn wrap_ext(file_ext: &str, ext_width: usize) -> String {
let config = Config::default();
wrap_function(&config, false, |p| p.print_ext(file_ext, ext_width))
}
fn wrap_files(config: &Config, git_bash: bool, files: &Vec<File>, total: &Total) -> String {
wrap_function(config, git_bash, |p| p.print_files(files, total, &Utc))
}
fn wrap_function<F>(config: &Config, git_bash: bool, func: F) -> String
where F: FnOnce(&mut Printer<BufferWrapper>) -> MyResult<()>
{
unsafe {
let mut buffer = String::new();
let writer = BufferWrapper::new(buffer.as_mut_vec());
let mut printer = Printer::new(&config, writer, git_bash);
func(&mut printer).unwrap();
return buffer;
}
}
fn create_files(drive: &str, abs_prefix: &str, rel_prefix: &str) -> (Vec<File>, Total) {
let abs_prefix = drive.to_string() + abs_prefix;
let link_path = drive.to_string() + "/etc/numbers/googolplex.txt";
let files = vec![
create_file(&abs_prefix, rel_prefix, "", "find", ".sh", None, EntryKind::File, 0o744, 10, 2023, 1, 1),
create_file(&abs_prefix, rel_prefix, "files", "", "", None, EntryKind::Dir, 0o755, 0, 2023, 12, 1),
create_file(&abs_prefix, rel_prefix, "files/colours", "", "", None, EntryKind::Dir, 0o755, 0, 2023, 12, 1),
create_file(&abs_prefix, rel_prefix, "files/colours", "paint", ".sh", None, EntryKind::File, 0o744, 20, 2023, 2, 1),
create_file(&abs_prefix, rel_prefix, "files/colours", "blue", ".txt", None, EntryKind::File, 0o644, 30, 2023, 3, 1),
create_file(&abs_prefix, rel_prefix, "files/colours", "green", ".txt", None, EntryKind::File, 0o644, 40, 2023, 4, 1),
create_file(&abs_prefix, rel_prefix, "files/colours", "red", ".txt", None, EntryKind::File, 0o644, 50, 2023, 5, 1),
create_file(&abs_prefix, rel_prefix, "files/numbers", "", "", None, EntryKind::Dir, 0o755, 0, 2023, 12, 1),
create_file(&abs_prefix, rel_prefix, "files/numbers", "count", ".sh", None, EntryKind::File, 0o744, 60, 2023, 6, 1),
create_file(&abs_prefix, rel_prefix, "files/numbers", "googolplex", ".txt", Some(&link_path), EntryKind::Link, 0o644, 999, 2023, 7, 1),
create_file(&abs_prefix, rel_prefix, "files/numbers/one two", "", "", None, EntryKind::Dir, 0o755, 0, 2023, 12, 1),
create_file(&abs_prefix, rel_prefix, "files/numbers/one two", "\"three\" 'four'", ".txt", None, EntryKind::File, 0o644, 70, 2023, 8, 1),
];
let total = create_total(&files);
return (files, total);
}
fn create_files_by_name(drive: &str, abs_prefix: &str, rel_prefix: &str) -> (Vec<File>, Total) {
let abs_prefix = drive.to_string() + abs_prefix;
let link_path = drive.to_string() + "/etc/numbers/googolplex.txt";
let files = vec![
create_file(&abs_prefix, rel_prefix, "files/colours", "blue", ".txt", None, EntryKind::File, 0o644, 30, 2023, 3, 1),
create_file(&abs_prefix, rel_prefix, "files/numbers", "count", ".sh", None, EntryKind::File, 0o744, 60, 2023, 6, 1),
create_file(&abs_prefix, rel_prefix, "", "find", ".sh", None, EntryKind::File, 0o744, 10, 2023, 1, 1),
create_file(&abs_prefix, rel_prefix, "files/numbers", "googolplex", ".txt", Some(&link_path), EntryKind::Link, 0o644, 999, 2023, 7, 1),
create_file(&abs_prefix, rel_prefix, "files/colours", "green", ".txt", None, EntryKind::File, 0o644, 40, 2023, 4, 1),
create_file(&abs_prefix, rel_prefix, "files/colours", "paint", ".sh", None, EntryKind::File, 0o744, 20, 2023, 2, 1),
create_file(&abs_prefix, rel_prefix, "files/colours", "red", ".txt", None, EntryKind::File, 0o644, 50, 2023, 5, 1),
create_file(&abs_prefix, rel_prefix, "files/numbers/one two", "\"three\" 'four'", ".txt", None, EntryKind::File, 0o644, 70, 2023, 8, 1),
];
let total = create_total(&files);
return (files, total);
}
fn create_file(
abs_prefix: &str,
rel_prefix: &str,
rel_suffix: &str,
file_name: &str,
file_ext: &str,
link_path: Option<&str>,
file_type: EntryKind,
file_mode: u32,
file_size: u64,
year: i32,
month: u32,
day: u32,
) -> File {
let abs_dir = PathBuf::from(abs_prefix).join(rel_suffix).clean();
let rel_dir = PathBuf::from(rel_prefix).join(rel_suffix).clean();
let file_depth = PathBuf::from(rel_suffix).join(file_name).components().count();
let link_path = link_path.map(PathBuf::from).map(|p| p.clean());
let file_name = format!("{file_name}{file_ext}");
let file_ext = String::from(file_ext);
let file_time = Utc.with_ymd_and_hms(year, month, day, 0, 0, 0).unwrap();
return File {
abs_dir,
rel_dir,
link_path,
file_depth,
file_name,
file_ext,
file_type,
file_mode,
file_size,
file_time,
};
}
fn create_total(files: &Vec<File>) -> Total {
let start_time = files.iter().map(|f| f.file_time).min();
let max_size = files.iter().map(|f| f.file_size).max().unwrap_or(0);
let total_size = files.iter().map(|f| f.file_size).sum();
let ext_width = files.iter().map(|f| f.file_ext.len()).max().unwrap_or(0);
let num_files = files.iter().filter(|f| f.file_type != EntryKind::Dir).count();
let num_dirs = files.iter().filter(|f| f.file_type == EntryKind::Dir).count();
return Total {
start_time,
max_size,
total_size,
ext_width,
num_files,
num_dirs,
};
}
struct BufferWrapper<'a> {
buffer: &'a mut Vec<u8>,
}
impl<'a> BufferWrapper<'a> {
fn new(buffer: &mut Vec<u8>) -> BufferWrapper {
BufferWrapper { buffer }
}
}
impl<'a> Write for BufferWrapper<'a> {
fn write(&mut self, buffer: &[u8]) -> io::Result<usize> {
self.buffer.write(buffer)
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
impl<'a> WriteColor for BufferWrapper<'a> {
fn supports_color(&self) -> bool {
false
}
fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
let bold = if spec.bold() { "Lt" } else { "Dk" };
let fg = match spec.fg() {
Some(Color::Black) => "Black",
Some(Color::Blue) => "Blue",
Some(Color::Green) => "Green",
Some(Color::Red) => "Red",
Some(Color::Cyan) => "Cyan",
Some(Color::Magenta) => "Magenta",
Some(Color::Yellow) => "Yellow",
Some(Color::White) => "White",
Some(_) => "Other",
None => "None",
};
write!(&mut self.buffer, "[{bold}{fg}]")?;
return Ok(());
}
fn reset(&mut self) -> io::Result<()> {
write!(&mut self.buffer, "[Reset]")?;
return Ok(());
}
}
}