Ran through and fixed clippy lints
This commit is contained in:
parent
455a2d36f9
commit
46c41e1c13
@ -69,7 +69,7 @@ impl File {
|
|||||||
Err(Error::InvalidChecksum)
|
Err(Error::InvalidChecksum)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => Ok(Self {
|
Checksum::Skip => Ok(Self {
|
||||||
len,
|
len,
|
||||||
checksum,
|
checksum,
|
||||||
data,
|
data,
|
||||||
|
@ -50,8 +50,8 @@ impl From<&FileType> for Flag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Flag {
|
impl Flag {
|
||||||
pub(crate) fn append_mode(&self, mode: u16) -> u16 {
|
pub(crate) fn append_mode(self, mode: u16) -> u16 {
|
||||||
let mask: u16 = u16::from(*self as u8) << 13;
|
let mask: u16 = u16::from(self as u8) << 13;
|
||||||
mode | mask
|
mode | mask
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +130,7 @@ impl FileType {
|
|||||||
match self {
|
match self {
|
||||||
Self::Normal(f) => f.write(writer)?,
|
Self::Normal(f) => f.write(writer)?,
|
||||||
Self::HardLink(s) | Self::SoftLink(s) => {
|
Self::HardLink(s) | Self::SoftLink(s) => {
|
||||||
let len = s.len() as u16;
|
let len = u16::try_from(s.len())?;
|
||||||
writer.write_all(&len.to_le_bytes())?;
|
writer.write_all(&len.to_le_bytes())?;
|
||||||
writer.write_all(s.as_bytes())?;
|
writer.write_all(s.as_bytes())?;
|
||||||
}
|
}
|
||||||
|
23
src/lib.rs
23
src/lib.rs
@ -1,3 +1,4 @@
|
|||||||
|
#![warn(clippy::all, clippy::pedantic)]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
@ -8,7 +9,7 @@ use std::{
|
|||||||
#[cfg(feature = "parallel")]
|
#[cfg(feature = "parallel")]
|
||||||
use {
|
use {
|
||||||
rayon::prelude::{IntoParallelRefIterator, ParallelIterator},
|
rayon::prelude::{IntoParallelRefIterator, ParallelIterator},
|
||||||
std::{ops::DerefMut, sync::mpsc::Sender},
|
std::sync::mpsc::Sender,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod checksum;
|
mod checksum;
|
||||||
@ -36,7 +37,9 @@ pub use stream::Message as StreamMessage;
|
|||||||
pub static MAGIC: [u8; 7] = [0x89, b'h', b'a', b'g', b'g', b'i', b's'];
|
pub static MAGIC: [u8; 7] = [0x89, b'h', b'a', b'g', b'g', b'i', b's'];
|
||||||
|
|
||||||
/// Creates a haggis archive from a list of files
|
/// Creates a haggis archive from a list of files
|
||||||
pub fn create_archive(path: &str, files: Vec<String>, algorithm: Algorithm) -> Result<(), Error> {
|
/// # Errors
|
||||||
|
/// Returns `crate::Error` if io fails or several other error conditions
|
||||||
|
pub fn create_archive(path: &str, files: &[String], algorithm: Algorithm) -> Result<(), Error> {
|
||||||
let fd = fs::OpenOptions::new()
|
let fd = fs::OpenOptions::new()
|
||||||
.create(true)
|
.create(true)
|
||||||
.truncate(true)
|
.truncate(true)
|
||||||
@ -47,16 +50,18 @@ pub fn create_archive(path: &str, files: Vec<String>, algorithm: Algorithm) -> R
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Streams a haggis archive over something which implements `Write`
|
/// Streams a haggis archive over something which implements `Write`
|
||||||
|
/// # Errors
|
||||||
|
/// Returns `crate::Error` if io fails or several other error conditions
|
||||||
pub fn stream_archive<W: Write>(
|
pub fn stream_archive<W: Write>(
|
||||||
mut writer: W,
|
mut writer: W,
|
||||||
files: Vec<String>,
|
files: &[String],
|
||||||
algorithm: Algorithm,
|
algorithm: Algorithm,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
writer.write_all(&MAGIC)?;
|
writer.write_all(&MAGIC)?;
|
||||||
let len = u32::try_from(files.len())?;
|
let len = u32::try_from(files.len())?;
|
||||||
writer.write_all(&len.to_le_bytes())?;
|
writer.write_all(&len.to_le_bytes())?;
|
||||||
let links = Mutex::new(HashMap::new());
|
let links = Mutex::new(HashMap::new());
|
||||||
for f in &files {
|
for f in files {
|
||||||
let node = Node::from_path(f, algorithm, &links)?;
|
let node = Node::from_path(f, algorithm, &links)?;
|
||||||
node.write(&mut writer)?;
|
node.write(&mut writer)?;
|
||||||
}
|
}
|
||||||
@ -74,10 +79,12 @@ pub enum Message {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a Haggis archive from a list of files, processing each file in parallel
|
/// Creates a Haggis archive from a list of files, processing each file in parallel
|
||||||
|
/// # Errors
|
||||||
|
/// Returns `crate::Error` if io fails or several other error conditions
|
||||||
#[cfg(feature = "parallel")]
|
#[cfg(feature = "parallel")]
|
||||||
pub fn par_create_archive(
|
pub fn par_create_archive(
|
||||||
path: &str,
|
path: &str,
|
||||||
files: Vec<String>,
|
files: &[String],
|
||||||
algorithm: Algorithm,
|
algorithm: Algorithm,
|
||||||
sender: &Sender<Message>,
|
sender: &Sender<Message>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
@ -88,10 +95,12 @@ pub fn par_create_archive(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Streams a Haggis archive from a list of files, processing each file in parallel
|
/// Streams a Haggis archive from a list of files, processing each file in parallel
|
||||||
|
/// # Errors
|
||||||
|
/// Returns `crate::Error` if io fails or several other error conditions
|
||||||
#[cfg(feature = "parallel")]
|
#[cfg(feature = "parallel")]
|
||||||
pub fn par_stream_archive<W: Write + Send>(
|
pub fn par_stream_archive<W: Write + Send>(
|
||||||
mut writer: W,
|
mut writer: W,
|
||||||
files: Vec<String>,
|
files: &[String],
|
||||||
algorithm: Algorithm,
|
algorithm: Algorithm,
|
||||||
sender: &Sender<Message>,
|
sender: &Sender<Message>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
@ -110,7 +119,7 @@ pub fn par_stream_archive<W: Write + Send>(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
if let Ok(mut writer) = writer.lock() {
|
if let Ok(mut writer) = writer.lock() {
|
||||||
let mut writer = writer.deref_mut();
|
let mut writer = &mut *writer;
|
||||||
if let Err(e) = node.write(&mut writer) {
|
if let Err(e) = node.write(&mut writer) {
|
||||||
s.send(Message::Err(e)).map_err(|_| Error::SenderError)?;
|
s.send(Message::Err(e)).map_err(|_| Error::SenderError)?;
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ pub fn geteuid() -> u32 {
|
|||||||
unsafe { libc::geteuid() }
|
unsafe { libc::geteuid() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::similar_names)]
|
||||||
pub fn chown(path: &str, uid: u32, gid: u32) -> Result<(), Error> {
|
pub fn chown(path: &str, uid: u32, gid: u32) -> Result<(), Error> {
|
||||||
let ret = unsafe { libc::chown(CString::new(path)?.as_ptr(), uid, gid) };
|
let ret = unsafe { libc::chown(CString::new(path)?.as_ptr(), uid, gid) };
|
||||||
if ret == 0 {
|
if ret == 0 {
|
||||||
|
29
src/node.rs
29
src/node.rs
@ -26,13 +26,13 @@ impl From<u32> for Kind {
|
|||||||
fn from(value: u32) -> Self {
|
fn from(value: u32) -> Self {
|
||||||
if value & 0o40000 != 0 {
|
if value & 0o40000 != 0 {
|
||||||
Self::Dir
|
Self::Dir
|
||||||
} else if value & 0o20000 != 0 {
|
} else if value & 0o20_000 != 0 {
|
||||||
Self::Char
|
Self::Char
|
||||||
} else if value & 0o60000 != 0 {
|
} else if value & 0o60_000 != 0 {
|
||||||
Self::Block
|
Self::Block
|
||||||
} else if value & 0o10000 != 0 {
|
} else if value & 0o10_000 != 0 {
|
||||||
Self::Pipe
|
Self::Pipe
|
||||||
} else if value & 0o100000 != 0 {
|
} else if value & 0o100_000 != 0 {
|
||||||
Self::Normal
|
Self::Normal
|
||||||
} else {
|
} else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
@ -58,16 +58,19 @@ pub struct Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Node {
|
impl Node {
|
||||||
|
#[allow(clippy::similar_names)]
|
||||||
/// Reads a `Node` from an archive file or stream of Nodes.
|
/// Reads a `Node` from an archive file or stream of Nodes.
|
||||||
/// > Note: this function reads an already created node. To create a new node
|
/// > Note: this function reads an already created node. To create a new node
|
||||||
/// > from a file, use the `from_path` method.
|
/// > from a file, use the `from_path` method.
|
||||||
|
/// # Errors
|
||||||
|
/// Returns `crate::Error` if io fails or certain other circumstances
|
||||||
pub fn read<T: Read>(reader: &mut T) -> Result<Self, Error> {
|
pub fn read<T: Read>(reader: &mut T) -> Result<Self, Error> {
|
||||||
let mut len = [0; 2];
|
let mut len = [0; 2];
|
||||||
reader.read_exact(&mut len)?;
|
reader.read_exact(&mut len)?;
|
||||||
let len = u16::from_le_bytes(len);
|
let len = u16::from_le_bytes(len);
|
||||||
if len == 0 {
|
if len == 0 {
|
||||||
return Ok(Self {
|
return Ok(Self {
|
||||||
name: "".to_string(),
|
name: String::new(),
|
||||||
mode: 0,
|
mode: 0,
|
||||||
uid: 0,
|
uid: 0,
|
||||||
gid: 0,
|
gid: 0,
|
||||||
@ -101,6 +104,8 @@ impl Node {
|
|||||||
/// > Note: this function saves the data to the archive format's on-disk
|
/// > Note: this function saves the data to the archive format's on-disk
|
||||||
/// > representation. To extract the contents of a `Node` and write out the
|
/// > representation. To extract the contents of a `Node` and write out the
|
||||||
/// > file it represents, use the `extract` method instead.
|
/// > file it represents, use the `extract` method instead.
|
||||||
|
/// # Errors
|
||||||
|
/// Returns `crate::Error` if io fails or certain other circumstances
|
||||||
pub fn write<T: Write>(&self, writer: &mut T) -> Result<(), Error> {
|
pub fn write<T: Write>(&self, writer: &mut T) -> Result<(), Error> {
|
||||||
let len: u16 = self.name.len().try_into()?;
|
let len: u16 = self.name.len().try_into()?;
|
||||||
writer.write_all(&len.to_le_bytes())?;
|
writer.write_all(&len.to_le_bytes())?;
|
||||||
@ -114,6 +119,7 @@ impl Node {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::similar_names)]
|
||||||
/// Creates a new node from a file which exists on the filesystem
|
/// Creates a new node from a file which exists on the filesystem
|
||||||
/// ### Parameters
|
/// ### Parameters
|
||||||
/// - path - the path to this file
|
/// - path - the path to this file
|
||||||
@ -122,6 +128,8 @@ impl Node {
|
|||||||
/// - links - this should be passed to each invocation of `from_path` used
|
/// - links - this should be passed to each invocation of `from_path` used
|
||||||
/// during the creation of a single archive, to identify hard links and to
|
/// during the creation of a single archive, to identify hard links and to
|
||||||
/// avoid writing their data out more than once.
|
/// avoid writing their data out more than once.
|
||||||
|
/// # Errors
|
||||||
|
/// Returns `crate::Error` if io fails or certain other circumstances
|
||||||
pub fn from_path(
|
pub fn from_path(
|
||||||
path: &str,
|
path: &str,
|
||||||
algorithm: Algorithm,
|
algorithm: Algorithm,
|
||||||
@ -150,9 +158,8 @@ impl Node {
|
|||||||
let inode = meta.ino();
|
let inode = meta.ino();
|
||||||
if let Some(target) = list.get(&inode).cloned() {
|
if let Some(target) = list.get(&inode).cloned() {
|
||||||
break 'blk FileType::HardLink(target);
|
break 'blk FileType::HardLink(target);
|
||||||
} else {
|
|
||||||
list.insert(inode, name.clone());
|
|
||||||
}
|
}
|
||||||
|
list.insert(inode, name.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let kind = Kind::from(mode);
|
let kind = Kind::from(mode);
|
||||||
@ -195,9 +202,8 @@ impl Node {
|
|||||||
checksum,
|
checksum,
|
||||||
data,
|
data,
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
return Err(Error::UnknownFileType);
|
|
||||||
}
|
}
|
||||||
|
return Err(Error::UnknownFileType);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let mode = Flag::from(&filetype).append_mode(u16::try_from(mode & 0o7777)?);
|
let mode = Flag::from(&filetype).append_mode(u16::try_from(mode & 0o7777)?);
|
||||||
@ -212,15 +218,16 @@ impl Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Recreates the original file on disk which this node represents
|
/// Recreates the original file on disk which this node represents
|
||||||
|
/// # Errors
|
||||||
|
/// Returns `crate::Error` if io fails or certain other circumstances
|
||||||
pub fn extract(&self, prefix: Option<&str>) -> Result<(), Error> {
|
pub fn extract(&self, prefix: Option<&str>) -> Result<(), Error> {
|
||||||
let euid = nix::geteuid();
|
let euid = nix::geteuid();
|
||||||
let path = 'blk: {
|
let path = 'blk: {
|
||||||
if let Some(prefix) = prefix {
|
if let Some(prefix) = prefix {
|
||||||
if self.name.starts_with('/') {
|
if self.name.starts_with('/') {
|
||||||
break 'blk format!("{prefix}{}", self.name);
|
break 'blk format!("{prefix}{}", self.name);
|
||||||
} else {
|
|
||||||
break 'blk format!("{prefix}/{}", self.name);
|
|
||||||
}
|
}
|
||||||
|
break 'blk format!("{prefix}/{}", self.name);
|
||||||
}
|
}
|
||||||
self.name.clone()
|
self.name.clone()
|
||||||
};
|
};
|
||||||
|
@ -28,6 +28,7 @@ impl Special {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(target_os = "freebsd", target_arch = "x86_64"))]
|
#[cfg(all(target_os = "freebsd", target_arch = "x86_64"))]
|
||||||
|
#[allow(clippy::cast_possible_truncation)]
|
||||||
pub(super) fn from_rdev(rdev: u64) -> Self {
|
pub(super) fn from_rdev(rdev: u64) -> Self {
|
||||||
Self {
|
Self {
|
||||||
major: ((rdev >> 8) & 0xff) as u32,
|
major: ((rdev >> 8) & 0xff) as u32,
|
||||||
@ -36,13 +37,14 @@ impl Special {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
|
#[allow(clippy::cast_possible_truncation)]
|
||||||
pub(super) fn from_rdev(rdev: u64) -> Self {
|
pub(super) fn from_rdev(rdev: u64) -> Self {
|
||||||
let mut major = 0;
|
let mut major = 0;
|
||||||
major |= (rdev & 0x00000000000fff00) >> 8;
|
major |= (rdev & 0x0000_0000_000f_ff00) >> 8;
|
||||||
major |= (rdev & 0xfffff00000000000) >> 32;
|
major |= (rdev & 0xffff_f000_0000_0000) >> 32;
|
||||||
let mut minor = 0;
|
let mut minor = 0;
|
||||||
minor |= rdev & 0x00000000000000ff;
|
minor |= rdev & 0x0000_0000_0000_00ff;
|
||||||
minor |= (rdev & 0x00000ffffff00000) >> 12;
|
minor |= (rdev & 0x0000_0fff_fff0_0000) >> 12;
|
||||||
Self {
|
Self {
|
||||||
major: major as u32,
|
major: major as u32,
|
||||||
minor: minor as u32,
|
minor: minor as u32,
|
||||||
|
@ -49,6 +49,9 @@ pub enum Message {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Read + Send> Stream<R> {
|
impl<R: Read + Send> Stream<R> {
|
||||||
|
/// Creates a new archive
|
||||||
|
/// # Errors
|
||||||
|
/// Returns `crate::Error` if io fails or several other error conditions
|
||||||
pub fn new(mut reader: R) -> Result<Self, Error> {
|
pub fn new(mut reader: R) -> Result<Self, Error> {
|
||||||
let mut buf = [0; 11];
|
let mut buf = [0; 11];
|
||||||
reader.read_exact(&mut buf)?;
|
reader.read_exact(&mut buf)?;
|
||||||
@ -60,6 +63,9 @@ impl<R: Read + Send> Stream<R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Extracts and archive
|
||||||
|
/// # Errors
|
||||||
|
/// Returns `crate::Error` if io fails or several other error conditions
|
||||||
pub fn extract(&mut self, prefix: Option<&str>) -> Result<(), Error> {
|
pub fn extract(&mut self, prefix: Option<&str>) -> Result<(), Error> {
|
||||||
for node in self {
|
for node in self {
|
||||||
node?.extract(prefix)?;
|
node?.extract(prefix)?;
|
||||||
@ -68,6 +74,9 @@ impl<R: Read + Send> Stream<R> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "parallel")]
|
#[cfg(feature = "parallel")]
|
||||||
|
/// Extracts and archive in parallel
|
||||||
|
/// # Errors
|
||||||
|
/// Returns `crate::Error` if io fails or several other error conditions
|
||||||
pub fn par_extract(
|
pub fn par_extract(
|
||||||
&mut self,
|
&mut self,
|
||||||
prefix: Option<&str>,
|
prefix: Option<&str>,
|
||||||
|
Loading…
Reference in New Issue
Block a user