Implement Display and PartialOrd for Listing struct

This commit is contained in:
Nathan Fisher 2023-12-23 19:03:12 -05:00
parent ae7c9b08b3
commit 9531c0268a
3 changed files with 100 additions and 5 deletions

View File

@ -1,9 +1,11 @@
use std::fmt;
use {
crate::{filetype::Flag, Error, Special},
std::io::{Read, Seek, SeekFrom},
};
#[derive(Debug)]
#[derive(Debug, PartialEq)]
pub enum Kind {
Normal(u64),
HardLink(String),
@ -16,6 +18,7 @@ pub enum Kind {
}
impl Kind {
#[allow(clippy::cast_possible_wrap)]
fn read<R: Read + Seek>(reader: &mut R, flag: Flag) -> Result<Self, Error> {
match flag {
Flag::Normal => {
@ -82,7 +85,7 @@ impl Kind {
}
}
#[derive(Debug)]
#[derive(Debug, PartialEq)]
pub struct Listing {
pub name: String,
pub uid: u32,
@ -92,7 +95,99 @@ pub struct Listing {
pub kind: Kind,
}
impl PartialOrd for Listing {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
if let (Kind::Directory, Kind::Directory) = (&self.kind, &other.kind) {
self.name.partial_cmp(&other.name)
} else if let Kind::Directory = self.kind {
Some(std::cmp::Ordering::Greater)
} else if let Kind::Directory = other.kind {
Some(std::cmp::Ordering::Less)
} else {
self.name.partial_cmp(&other.name)
}
}
}
impl fmt::Display for Listing {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}{}{}{}{}{}{}{}{}{} {}:{} {:>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 & 0o4100 != 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 & 0o2010 != 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 & 0o1001 != 0 => "t",
m if m & 0o1 != 0 => "x",
_ => "-",
},
self.uid,
self.gid,
match self.kind {
Kind::Normal(s) => s,
_ => 0,
},
)?;
match self.kind {
Kind::Directory | Kind::Fifo | Kind::Normal(_) => write!(f, "{}", self.name),
Kind::HardLink(ref tgt) => write!(f, "{}=>{}", self.name, tgt),
Kind::SoftLink(ref tgt) => write!(f, "{}->{}", self.name, tgt),
Kind::Character(ref sp) | Kind::Block(ref sp) => {
write!(f, "{} {},{}", self.name, sp.major, sp.minor)
}
Kind::Eof => unreachable!(),
}
}
}
impl Listing {
/// Reads all metadata from a haggis Node without reading the file's actual
/// data.
/// # Errors
/// Can return an error if IO fails
#[allow(clippy::similar_names)]
pub fn read<R: Read + Seek>(reader: &mut R) -> Result<Self, Error> {
let mut len = [0; 2];
reader.read_exact(&mut len)?;

View File

@ -4,7 +4,7 @@ use {
};
/// Represents the major and minor numbers of a Unix special Device node
#[derive(Debug)]
#[derive(Debug, PartialEq)]
pub struct Special {
pub major: u32,
pub minor: u32,
@ -32,7 +32,7 @@ impl Special {
pub(super) fn from_rdev(rdev: u64) -> Self {
Self {
major: ((rdev >> 8) & 0xff) as u32,
minor: (rdev & 0xffff00ff) as u32,
minor: (rdev & 0xffff_00ff) as u32,
}
}

View File

@ -63,7 +63,7 @@ impl<R: Read + Send> Stream<R> {
}
}
/// Extracts and archive
/// Extracts an archive
/// # Errors
/// Returns `crate::Error` if io fails or several other error conditions
pub fn extract(&mut self, prefix: Option<&str>) -> Result<(), Error> {