Add print_color for archive listings, format dates in archive listings

This commit is contained in:
Nathan Fisher 2023-12-30 23:40:57 -05:00
parent 97643b58e8
commit 63b414b7fd
3 changed files with 183 additions and 2 deletions

41
Cargo.lock generated
View File

@ -171,6 +171,7 @@ dependencies = [
"rayon", "rayon",
"sha1", "sha1",
"sha2", "sha2",
"termcolor",
] ]
[[package]] [[package]]
@ -345,6 +346,15 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "termcolor"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449"
dependencies = [
"winapi-util",
]
[[package]] [[package]]
name = "typenum" name = "typenum"
version = "1.16.0" version = "1.16.0"
@ -417,6 +427,37 @@ version = "0.2.89"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
dependencies = [
"winapi",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]] [[package]]
name = "windows-core" name = "windows-core"
version = "0.52.0" version = "0.52.0"

View File

@ -6,6 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features] [features]
parallel = ["dep:rayon"] parallel = ["dep:rayon"]
color = ["dep:termcolor"]
[dependencies] [dependencies]
chrono = "0.4" chrono = "0.4"
@ -14,3 +15,4 @@ md-5 = "0.10"
rayon = { version = "1.7", optional = true } rayon = { version = "1.7", optional = true }
sha1 = "0.10" sha1 = "0.10"
sha2 = "0.10" sha2 = "0.10"
termcolor = { version = "1.4", optional = true }

View File

@ -1,3 +1,9 @@
#[cfg(feature = "color")]
use {
std::io::Write,
termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor},
};
use { use {
crate::{filetype::Flag, Error, Special}, crate::{filetype::Flag, Error, Special},
chrono::NaiveDateTime, chrono::NaiveDateTime,
@ -109,10 +115,11 @@ impl Ord for Listing {
} }
impl fmt::Display for Listing { impl fmt::Display for Listing {
#[allow(clippy::cast_possible_wrap)]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!( write!(
f, f,
"{}{}{}{}{}{}{}{}{}{} {:>4}:{:<4} {:>10} {} ", "{}{}{}{}{}{}{}{}{}{} {:>4}:{:<4} {:>10} ",
match self.kind { match self.kind {
Kind::Normal(_) => "-", Kind::Normal(_) => "-",
Kind::HardLink(_) => "L", Kind::HardLink(_) => "L",
@ -168,8 +175,11 @@ impl fmt::Display for Listing {
Kind::Normal(s) => s, Kind::Normal(s) => s,
_ => 0, _ => 0,
}, },
NaiveDateTime::from_timestamp_opt(self.mtime as i64, 0).unwrap(),
)?; )?;
match NaiveDateTime::from_timestamp_opt(self.mtime as i64, 0) {
Some(dt) => write!(f, "{dt}")?,
_ => write!(f, "{:>19} ", self.mtime)?,
}
match self.kind { match self.kind {
Kind::Directory | Kind::Fifo | Kind::Normal(_) => write!(f, "{}", self.name), Kind::Directory | Kind::Fifo | Kind::Normal(_) => write!(f, "{}", self.name),
Kind::HardLink(ref tgt) => write!(f, "{}=>{}", self.name, tgt), Kind::HardLink(ref tgt) => write!(f, "{}=>{}", self.name, tgt),
@ -223,6 +233,134 @@ impl Listing {
kind, kind,
}) })
} }
#[allow(clippy::cast_possible_wrap)]
#[cfg(feature = "color")]
pub fn print_color(&self) -> Result<(), Error> {
print!(
"{}{}{}{}{}{}{}{}{}{} {:>4}:{:<4} {:>10} ",
match self.kind {
Kind::Normal(_) => "-",
Kind::HardLink(_) => "L",
Kind::SoftLink(_) => "l",
Kind::Directory => "d",
Kind::Character(_) => "c",
Kind::Block(_) => "b",
Kind::Fifo => "p",
Kind::Eof => return Ok(()),
},
match self.mode {
m if m & 0o400 != 0 => "r",
_ => "-",
},
match self.mode {
m if m & 0o200 != 0 => "w",
_ => "-",
},
match self.mode {
m if m & 0o4000 != 0 => "S",
m if m & 0o100 != 0 => "x",
_ => "-",
},
match self.mode {
m if m & 0o40 != 0 => "r",
_ => "-",
},
match self.mode {
m if m & 0o20 != 0 => "w",
_ => "-",
},
match self.mode {
m if m & 0o2000 != 0 => "S",
m if m & 0o10 != 0 => "x",
_ => "-",
},
match self.mode {
m if m & 0o4 != 0 => "r",
_ => "-",
},
match self.mode {
m if m & 0o2 != 0 => "w",
_ => "-",
},
match self.mode {
m if m & 0o1000 != 0 => "t",
m if m & 0o1 != 0 => "x",
_ => "-",
},
self.uid,
self.gid,
match self.kind {
Kind::Normal(s) => s,
_ => 0,
},
);
match NaiveDateTime::from_timestamp_opt(self.mtime as i64, 0) {
Some(dt) => print!("{dt}"),
_ => print!("{:>19} ", self.mtime),
}
let mut stdout = StandardStream::stdout(ColorChoice::Auto);
match self.kind {
Kind::Normal(_) => println!("{}", self.name),
Kind::Directory => {
stdout.set_color(ColorSpec::new().set_fg(Some(Color::Blue)))?;
writeln!(&mut stdout, "{}", self.name)?;
stdout.reset()?;
}
Kind::Fifo => {
stdout.set_color(ColorSpec::new().set_fg(Some(Color::Yellow)))?;
writeln!(&mut stdout, "{}", self.name)?;
stdout.reset()?;
}
Kind::HardLink(ref tgt) => {
stdout.set_color(ColorSpec::new().set_fg(Some(Color::Cyan)))?;
write!(&mut stdout, "{}", self.name)?;
stdout.reset()?;
println!(" => {tgt}");
}
Kind::SoftLink(ref tgt) => {
stdout.set_color(ColorSpec::new().set_fg(Some(Color::Cyan)))?;
write!(&mut stdout, "{}", self.name)?;
stdout.reset()?;
println!(" -> {tgt}");
}
Kind::Character(ref sp) | Kind::Block(ref sp) => {
stdout.set_color(ColorSpec::new().set_fg(Some(Color::Yellow)))?;
write!(&mut stdout, "{}", self.name)?;
stdout.reset()?;
println!(" {},{}", sp.major, sp.minor);
}
Kind::Eof => unreachable!(),
}
Ok(())
}
#[cfg(feature = "color")]
pub fn print_color_simple(&self) -> Result<(), Error> {
let mut stdout = StandardStream::stdout(ColorChoice::Auto);
match self.kind {
Kind::Normal(_) => println!("{}", self.name),
Kind::Directory => {
stdout.set_color(ColorSpec::new().set_fg(Some(Color::Blue)))?;
writeln!(&mut stdout, "{}", self.name)?;
}
Kind::Fifo => {
stdout.set_color(ColorSpec::new().set_fg(Some(Color::Yellow)))?;
writeln!(&mut stdout, "{}", self.name)?;
}
Kind::HardLink(_) | Kind::SoftLink(_) => {
stdout.set_color(ColorSpec::new().set_fg(Some(Color::Cyan)))?;
write!(&mut stdout, "{}", self.name)?;
}
Kind::Character(_) | Kind::Block(_) => {
stdout.set_color(ColorSpec::new().set_fg(Some(Color::Yellow)))?;
write!(&mut stdout, "{}", self.name)?;
}
Kind::Eof => unreachable!(),
}
stdout.reset()?;
Ok(())
}
} }
#[cfg(test)] #[cfg(test)]