Add ListingStream type

This commit is contained in:
Nathan Fisher 2023-12-29 23:52:05 -05:00
parent 3c708430ae
commit 2591d102d6
5 changed files with 67 additions and 10 deletions

View File

@ -17,6 +17,7 @@ mod error;
mod file; mod file;
mod filetype; mod filetype;
mod listing; mod listing;
mod listing_stream;
pub(crate) mod nix; pub(crate) mod nix;
mod node; mod node;
mod special; mod special;
@ -28,6 +29,7 @@ pub use {
file::File, file::File,
filetype::FileType, filetype::FileType,
listing::Listing, listing::Listing,
listing_stream::ListingStream,
node::Node, node::Node,
special::Special, special::Special,
stream::Stream, stream::Stream,

View File

@ -7,7 +7,7 @@ use {
}, },
}; };
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq, Eq)]
pub enum Kind { pub enum Kind {
Normal(u64), Normal(u64),
HardLink(String), HardLink(String),
@ -80,7 +80,7 @@ impl Kind {
} }
} }
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq, Eq)]
pub struct Listing { pub struct Listing {
pub name: String, pub name: String,
pub uid: u32, pub uid: u32,
@ -92,11 +92,17 @@ pub struct Listing {
impl PartialOrd for Listing { impl PartialOrd for Listing {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Listing {
fn cmp(&self, other: &Self) -> Ordering {
match (&self.kind, &other.kind) { match (&self.kind, &other.kind) {
(Kind::Directory, Kind::Directory) => self.name.partial_cmp(&other.name), (Kind::Directory, Kind::Directory) => self.name.cmp(&other.name),
(Kind::Directory, _) => Some(Ordering::Less), (Kind::Directory, _) => Ordering::Less,
(_, Kind::Directory) => Some(Ordering::Greater), (_, Kind::Directory) => Ordering::Greater,
_ => self.name.partial_cmp(&other.name), _ => self.name.cmp(&other.name),
} }
} }
} }

51
src/listing_stream.rs Normal file
View File

@ -0,0 +1,51 @@
use {
crate::{listing::Kind, Error, Listing, MAGIC},
std::{
io::{ErrorKind, Read, Seek},
iter::Iterator,
},
};
#[derive(Debug)]
pub struct ListingStream<R: Read + Send + Seek> {
pub length: u32,
reader: R,
}
impl<R: Read + Send + Seek> Iterator for ListingStream<R> {
type Item = Result<Listing, Error>;
fn next(&mut self) -> Option<Self::Item> {
match Listing::read(&mut self.reader) {
Err(Error::Io(e)) if e.kind() == ErrorKind::UnexpectedEof => None,
Ok(f) => match f.kind {
Kind::Eof => None,
_ => Some(Ok(f)),
},
x => Some(x),
}
}
}
impl<R: Read + Send + Seek> ListingStream<R> {
pub fn new(mut reader: R) -> Result<Self, Error> {
let mut buf = [0; 11];
reader.read_exact(&mut buf)?;
let length = u32::from_le_bytes(buf[7..].try_into()?);
if buf[0..7] == MAGIC {
Ok(Self { length, reader })
} else {
Err(Error::InvalidMagic)
}
}
pub fn list(&mut self) -> Result<Vec<Listing>, Error> {
let mut list = vec![];
for listing in self {
let listing = listing?;
list.push(listing);
}
list.sort();
Ok(list)
}
}

View File

@ -4,7 +4,7 @@ use {
}; };
/// Represents the major and minor numbers of a Unix special Device node /// Represents the major and minor numbers of a Unix special Device node
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq, Eq)]
pub struct Special { pub struct Special {
pub major: u32, pub major: u32,
pub minor: u32, pub minor: u32,

View File

@ -1,5 +1,3 @@
use crate::MAGIC;
#[cfg(feature = "parallel")] #[cfg(feature = "parallel")]
use { use {
crate::FileType, crate::FileType,
@ -7,7 +5,7 @@ use {
std::sync::mpsc::Sender, std::sync::mpsc::Sender,
}; };
use { use {
crate::{Error, Node}, crate::{Error, Node, MAGIC},
std::{ std::{
io::{ErrorKind, Read}, io::{ErrorKind, Read},
iter::Iterator, iter::Iterator,