Fix Clippy lints and improve documentation

This commit is contained in:
Nathan Fisher 2024-01-17 01:58:36 -05:00
parent ab259da64b
commit c60e385dd0
10 changed files with 145 additions and 99 deletions

140
Cargo.lock generated
View File

@ -75,55 +75,37 @@ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
[[package]]
name = "cpufeatures"
version = "0.2.8"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c"
checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504"
dependencies = [
"libc",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.3"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef"
checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
dependencies = [
"cfg-if",
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.15"
version = "0.9.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7"
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
dependencies = [
"autocfg",
"cfg-if",
"crossbeam-utils",
"memoffset",
"scopeguard",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.16"
version = "0.8.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294"
dependencies = [
"cfg-if",
]
checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
[[package]]
name = "crypto-common"
@ -147,9 +129,9 @@ dependencies = [
[[package]]
name = "either"
version = "1.8.1"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
[[package]]
name = "generic-array"
@ -174,12 +156,6 @@ dependencies = [
"termcolor",
]
[[package]]
name = "hermit-abi"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
[[package]]
name = "iana-time-zone"
version = "0.1.59"
@ -205,18 +181,18 @@ dependencies = [
[[package]]
name = "js-sys"
version = "0.3.66"
version = "0.3.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca"
checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "libc"
version = "0.2.147"
version = "0.2.152"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7"
[[package]]
name = "log"
@ -226,22 +202,14 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "md-5"
version = "0.10.5"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca"
checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf"
dependencies = [
"cfg-if",
"digest",
]
[[package]]
name = "memoffset"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c"
dependencies = [
"autocfg",
]
[[package]]
name = "num-traits"
version = "0.2.17"
@ -251,16 +219,6 @@ dependencies = [
"autocfg",
]
[[package]]
name = "num_cpus"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
name = "once_cell"
version = "1.19.0"
@ -269,27 +227,27 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "proc-macro2"
version = "1.0.71"
version = "1.0.76"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75cb1540fadbd5b8fbccc4dddad2734eba435053f725621c070711a14bb5f4b8"
checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.33"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rayon"
version = "1.7.0"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b"
checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1"
dependencies = [
"either",
"rayon-core",
@ -297,27 +255,19 @@ dependencies = [
[[package]]
name = "rayon-core"
version = "1.11.0"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d"
checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed"
dependencies = [
"crossbeam-channel",
"crossbeam-deque",
"crossbeam-utils",
"num_cpus",
]
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "sha1"
version = "0.10.5"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
dependencies = [
"cfg-if",
"cpufeatures",
@ -326,9 +276,9 @@ dependencies = [
[[package]]
name = "sha2"
version = "0.10.7"
version = "0.10.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8"
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
dependencies = [
"cfg-if",
"cpufeatures",
@ -337,9 +287,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.43"
version = "2.0.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee659fb5f3d355364e1f3e5bc10fb82068efbf824a1e9d1c9504244a6469ad53"
checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
dependencies = [
"proc-macro2",
"quote",
@ -348,18 +298,18 @@ dependencies = [
[[package]]
name = "termcolor"
version = "1.4.0"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449"
checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
dependencies = [
"winapi-util",
]
[[package]]
name = "typenum"
version = "1.16.0"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]]
name = "unicode-ident"
@ -375,9 +325,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "wasm-bindgen"
version = "0.2.89"
version = "0.2.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e"
checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
@ -385,9 +335,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.89"
version = "0.2.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826"
checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd"
dependencies = [
"bumpalo",
"log",
@ -400,9 +350,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.89"
version = "0.2.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2"
checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@ -410,9 +360,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.89"
version = "0.2.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283"
checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7"
dependencies = [
"proc-macro2",
"quote",
@ -423,9 +373,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.89"
version = "0.2.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f"
checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b"
[[package]]
name = "winapi"

View File

@ -12,7 +12,7 @@ color = ["dep:termcolor"]
chrono = "0.4"
libc = "0.2"
md-5 = "0.10"
rayon = { version = "1.7", optional = true }
rayon = { version = "1.8", optional = true }
sha1 = "0.10"
sha2 = "0.10"
termcolor = { version = "1.4", optional = true }

View File

@ -6,11 +6,26 @@ use {
},
};
/// A hashing algorithm used for checking file integrity
#[derive(Clone, Copy, Debug)]
pub enum Algorithm {
/// The [md5](https://www.ietf.org/rfc/rfc1321.txt) hash is
/// a widely deployed fast hash included for completeness.
/// As md5 is not cryptographically secure and collisions have
/// been proven to occur, the newer sha\[x\] algorithms are to
/// be preferred
Md5,
/// The [sha1](https://datatracker.ietf.org/doc/html/rfc3174)
/// hash is competitive in speed to md5 while having significantly
/// lower possibility of hash collision. Use this hash method if
/// you want goot file integrity checking coupled with low overhead.
Sha1,
/// The [sha256](https://tools.ietf.org/html/rfc6234) hash is
/// a cryptographically secure hash that is stronger than both
/// md5 and sha1. Use this hash when the importance of file
/// integrity far outweighs performance considerations.
Sha256,
/// Do not use file integrity checks
Skip,
}
@ -31,7 +46,8 @@ impl FromStr for Algorithm {
/// Optional checksumming for individual files
#[derive(Debug)]
pub enum Checksum {
/// Md5 checksumming, fastest
/// Md5 checksumming, fastest, but collisions have occurred. Not recommended
/// for production use.
Md5([u8; 16]),
/// Sha1 checksumming. On par with md5.
Sha1([u8; 20]),
@ -45,6 +61,9 @@ pub enum Checksum {
}
impl Checksum {
/// Reads a `Checksum` item into memory from a byte stream
/// # Errors
/// Returns an `Error` if io fails or the archive is incorrectly formatted
pub(crate) fn read<T: Read>(reader: &mut T) -> Result<Self, Error> {
let mut buf = [0; 1];
reader.read_exact(&mut buf)?;
@ -68,6 +87,9 @@ impl Checksum {
}
}
/// Writes a `Checksum` into a byte stream
/// # Errors
/// Returns `Error` if io fails
pub(crate) fn write<T: Write>(&self, writer: &mut T) -> Result<(), Error> {
match self {
Self::Md5(sum) => {

View File

@ -18,6 +18,10 @@ pub struct File {
}
impl File {
/// Read a `File` structure from a stream of bytes
/// # Errors
/// Can return `Error` if io fails or the byte stream is not a valid
/// **Haggis** archive
pub(crate) fn read<T: Read>(reader: &mut T) -> Result<Self, Error> {
let mut len = [0; 8];
reader.read_exact(&mut len)?;
@ -77,6 +81,9 @@ impl File {
}
}
/// Writes a `File` structure into a stream of bytes
/// # Errors
/// Can return `Error` if io fails
pub(crate) fn write<T: Write>(&self, writer: &mut T) -> Result<(), Error> {
writer.write_all(&self.len.to_le_bytes())?;
Checksum::write(&self.checksum, writer)?;

View File

@ -74,6 +74,9 @@ pub fn stream_archive<W: Write>(
Ok(())
}
/// A message to be passed to another thread when a `Node` is created or saved.
/// Useful when creating a `Node` in a background thread and displaying progress
/// in the main thread
#[cfg(feature = "parallel")]
#[derive(Debug)]
pub enum Message {

View File

@ -14,15 +14,32 @@ use {
},
};
/// An item representing the `Filetype` of a `Node` without
/// including a file's actual data or checksum.
#[derive(Debug, PartialEq, Eq)]
pub enum Kind {
/// A regular file. The associated `u64` represents the files
/// size in bytes.
Normal(u64),
/// A hard link to another member of this archive. The associated
/// `String` represents the target of the link
HardLink(String),
/// A symlink to another file. The associated `String` represents
/// the target of the link.
SoftLink(String),
/// A directory entry
Directory,
/// A character (buffered) device file. The associated `Special`
/// struct represents the **major** and **minor** numbers of the
/// device file.
Character(Special),
/// A block (non-buffered) device file. The associated `Special`
/// struct represents the **major** and **minor** numbers of the
/// device file.
Block(Special),
/// A named pipe
Fifo,
/// The end of the archive
Eof,
}
@ -42,6 +59,8 @@ impl From<FileType> for Kind {
}
impl Kind {
/// Reads an item from a stream of bytes. The stream can be anything implementing
/// both `Read` and `Seek`
#[allow(clippy::cast_possible_wrap)]
fn read<R: Read + Seek>(reader: &mut R, flag: Flag) -> Result<Self, Error> {
match flag {
@ -102,6 +121,17 @@ impl Kind {
}
}
/// An item representing a `Node` with all relavent metadata minus
/// the bytes making up the file and the file's checksum. Useful
/// for examining the contents of an archive by printing file listings.
/// > Note: Because this type can be read from an archive while skipping over
/// > the bytes making up the file's contents and checksum, it can be created
/// > faster than a `Node` and takes up less space in memory. However, it may
/// > not always be possible to create a `Listing` directly, as in the case
/// > where the underlying byte stream does not implement `Seek`, such as with
/// > a zstd compressed archive. In this case, a `Node` can be read from the
/// > stream and converted to a `Listing` using `From`, which will still save
/// > on overall memory usage when listing all files in an archive.
#[derive(Debug, PartialEq, Eq)]
pub struct Listing {
pub name: String,
@ -262,6 +292,11 @@ impl Listing {
})
}
/// Prints a line with relavent metadata included,
/// colorizing the filename based on the filetype.
/// Similar to GNU `ls --long --color auto`
/// # Errors
/// Can return an `Error` if stdout is unavailable
#[allow(clippy::cast_possible_wrap)]
#[cfg(feature = "color")]
pub fn print_color(&self) -> Result<(), Error> {
@ -363,6 +398,10 @@ impl Listing {
Ok(())
}
/// Prints just the filename representing the `Listing` item,
/// coloring each line based on the filetype
/// # Errors
/// Can return an `Error` if stdout is unavailable
#[cfg(feature = "color")]
pub fn print_color_simple(&self) -> Result<(), Error> {
let mut stdout = StandardStream::stdout(ColorChoice::Auto);

View File

@ -6,6 +6,8 @@ use {
},
};
/// An iterator over `Listing` items, used for displaying the contents of a
/// *Haggis* archive
#[derive(Debug)]
pub struct ListingStream<R: Read + Send> {
pub length: u32,
@ -28,6 +30,12 @@ impl<R: Read + Send + Seek> Iterator for ListingStream<R> {
}
impl<R: Read + Send + Seek> ListingStream<R> {
/// Creates a new `ListingStream` from the given reader,
/// which should be a stream of bytes making up a valid Haggis
/// archive.
///# Errors
/// Can return `Error` if an io error occurs or if the arvhice
/// is incorrectly formatted
pub fn new(mut reader: R) -> Result<Self, Error> {
let mut buf = [0; 11];
reader.read_exact(&mut buf)?;
@ -39,6 +47,11 @@ impl<R: Read + Send + Seek> ListingStream<R> {
}
}
/// Creates a `Vec` of `Listing` structs representing every `Node`
/// making up the archive
/// # Errors
/// Can return `Error` if an io error occurs or if the archive is
/// incorrectly formatted
pub fn list(&mut self) -> Result<Vec<Listing>, Error> {
let mut list = vec![];
for listing in self {

View File

@ -10,6 +10,8 @@ pub fn geteuid() -> u32 {
unsafe { libc::geteuid() }
}
/// A wrapper around the libc **chown** function, used for changing file
/// ownership
#[allow(clippy::similar_names)]
pub fn chown(path: &str, uid: u32, gid: u32) -> Result<(), Error> {
let ret = unsafe { libc::chown(CString::new(path)?.as_ptr(), uid, gid) };
@ -20,6 +22,8 @@ pub fn chown(path: &str, uid: u32, gid: u32) -> Result<(), Error> {
}
}
/// A wrapper around the libc **chmod** function, used for changing file
/// permissions
#[cfg(target_os = "linux")]
pub fn chmod(path: &str, mode: u32) -> Result<(), Error> {
let ret = unsafe { libc::chmod(CString::new(path)?.as_ptr(), mode) };
@ -30,6 +34,8 @@ pub fn chmod(path: &str, mode: u32) -> Result<(), Error> {
}
}
/// A wrapper around the libc **chmod** function, used for changing file
/// permissions
#[cfg(target_os = "freebsd")]
pub fn chmod(path: &str, mode: u32) -> Result<(), Error> {
let ret = unsafe { libc::chmod(CString::new(path)?.as_ptr(), mode.try_into()?) };
@ -40,6 +46,7 @@ pub fn chmod(path: &str, mode: u32) -> Result<(), Error> {
}
}
/// A wrapper around the libc **mkfifo** function, for creating named pipes
#[cfg(target_os = "linux")]
pub fn mkfifo(path: &str, mode: u32) -> Result<(), Error> {
let ret = unsafe { libc::mkfifo(CString::new(path)?.as_ptr(), mode) };
@ -50,6 +57,7 @@ pub fn mkfifo(path: &str, mode: u32) -> Result<(), Error> {
}
}
/// A wrapper around the libc **mkfifo** function, for creating named pipes
#[cfg(target_os = "freebsd")]
pub fn mkfifo(path: &str, mode: u32) -> Result<(), Error> {
let ret = unsafe { libc::mkfifo(CString::new(path)?.as_ptr(), mode.try_into()?) };
@ -60,6 +68,7 @@ pub fn mkfifo(path: &str, mode: u32) -> Result<(), Error> {
}
}
/// A wrapper around the libc **mknod** function, for creating Unix device files
#[cfg(target_os = "linux")]
pub fn mknod(path: &str, mode: u32, major: u32, minor: u32) -> Result<(), Error> {
let dev = libc::makedev(major, minor);
@ -71,6 +80,7 @@ pub fn mknod(path: &str, mode: u32, major: u32, minor: u32) -> Result<(), Error>
}
}
/// A wrapper around the libc **mknod** function, for creating Unix device files
#[cfg(target_os = "freebsd")]
pub fn mknod(path: &str, mode: u32, major: u32, minor: u32) -> Result<(), Error> {
let dev = libc::makedev(major, minor);

View File

@ -64,7 +64,7 @@ impl Node {
/// > Note: this function reads an already created node. To create a new node
/// > from a file, use the `from_path` method.
/// # Errors
/// Returns `crate::Error` if io fails or certain other circumstances
/// Returns `crate::Error` if io fails or the archive is incorrectly formatted
pub fn read<T: Read>(reader: &mut T) -> Result<Self, Error> {
let mut len = [0; 2];
reader.read_exact(&mut len)?;
@ -106,7 +106,7 @@ impl Node {
/// > representation. To extract the contents of a `Node` and write out the
/// > file it represents, use the `extract` method instead.
/// # Errors
/// Returns `crate::Error` if io fails or certain other circumstances
/// Returns `crate::Error` if io fails
pub fn write<T: Write>(&self, writer: &mut T) -> Result<(), Error> {
let len: u16 = self.name.len().try_into()?;
writer.write_all(&len.to_le_bytes())?;

View File

@ -36,6 +36,8 @@ impl<R: Read + Send> Iterator for Stream<R> {
}
}
/// A message to be passed from a background thread to a foreground thread when
/// a `Node` extraction has finished
#[cfg(feature = "parallel")]
#[derive(Debug)]
pub enum Message {