Skip to content

Commit

Permalink
Add walkdir as rrd replacement
Browse files Browse the repository at this point in the history
  • Loading branch information
szeweq committed Jun 2, 2024
1 parent 7f6478b commit 2fb0207
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 114 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ zip = {version = "^2.1.0", default-features = false}
toml = "^0.8.0"
serde = "1.0"
anyhow = "1.0"
walkdir = "2.5"

[[bin]]
name = "mc-repack"
Expand All @@ -32,6 +33,7 @@ crossbeam-channel = "^0.5.8"
anyhow = {workspace = true}
serde = {workspace = true}
toml = {workspace = true, features = ["preserve_order"]}
walkdir = {workspace = true}
pathdiff = "^0.2.1"

# CLI Dependencies
Expand Down
1 change: 1 addition & 0 deletions lib-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ flate2 = "^1.0.26"
json_comments = "0.2"
toml = {optional = true, workspace = true, features = ["preserve_order"]}
zopfli = {version = "^0.8.0", optional = true}
walkdir = {workspace = true}
state = "0.6"

[lints.rust]
Expand Down
77 changes: 21 additions & 56 deletions lib-core/src/entry/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,26 @@ use crate::fop::FileOp;
use super::{EntryReader, EntryReaderSpec, EntrySaver, EntrySaverSpec, EntryType};

/// An entry reader implementation for a file system. It reads a file tree from a provided directory.
pub struct FSEntryReader<I: Iterator<Item = io::Result<(Option<bool>, Box<Path>)>>> {
pub struct FSEntryReader<I: ExactSizeIterator<Item = io::Result<(Option<bool>, Box<Path>)>>> {
src_dir: Box<Path>,
iter: std::iter::Peekable<I>
}
impl FSEntryReader<RecursiveReadDir> {
impl FSEntryReader<std::vec::IntoIter<io::Result<(Option<bool>, Box<Path>)>>> {
/// Creates an entry reader with a source directory path.
pub fn new(src_dir: Box<Path>) -> EntryReader<Self> {
let iter: std::iter::Peekable<RecursiveReadDir> = RecursiveReadDir::new(src_dir.clone()).peekable();
EntryReader(Self { src_dir, iter })
let files = walkdir::WalkDir::new(src_dir.clone()).into_iter().map(check_dir_entry).collect::<Vec<_>>();
EntryReader(Self { src_dir, iter: files.into_iter().peekable() })
}
}
impl <I: Iterator<Item = io::Result<(Option<bool>, Box<Path>)>>> FSEntryReader<I> {
impl <I: ExactSizeIterator<Item = io::Result<(Option<bool>, Box<Path>)>>> FSEntryReader<I> {
/// Creates an entry reader with a source directory path and a custom iterator.
pub fn custom(src_dir: Box<Path>, iter: I) -> EntryReader<Self> {
EntryReader(Self { src_dir, iter: iter.peekable() })
}
}
impl <I: Iterator<Item = io::Result<(Option<bool>, Box<Path>)>>> EntryReaderSpec for FSEntryReader<I> {
impl <I: ExactSizeIterator<Item = io::Result<(Option<bool>, Box<Path>)>>> EntryReaderSpec for FSEntryReader<I> {
fn len(&self) -> usize {
RecursiveReadDir::new(self.src_dir.clone()).filter(|x| x.is_ok()).count()
self.iter.len()
}
fn peek(&mut self) -> Option<(Option<bool>, Box<str>)> {
self.iter.peek().map(|x| {
Expand Down Expand Up @@ -85,54 +85,19 @@ impl EntrySaverSpec for FSEntrySaver {
}
}

struct RecursiveReadDir {
dirs: Vec<Box<Path>>,
cur: Option<Box<fs::ReadDir>>
}
impl RecursiveReadDir {
fn new(src_dir: Box<Path>) -> Self {
Self { dirs: vec![src_dir], cur: None }
}
}
impl Iterator for RecursiveReadDir {
type Item = std::io::Result<(Option<bool>, Box<Path>)>;
fn next(&mut self) -> Option<Self::Item> {
let rd = match self.cur {
None => {
let p = self.dirs.pop()?;
match fs::read_dir(p) {
Ok(rd) => {
self.cur = Some(Box::new(rd));
self.cur.as_mut().unwrap()
},
Err(e) => return Some(Err(e))
}
}
Some(ref mut rd) => rd
};
let e = match rd.next() {
None => {
self.cur = None;
return self.next()
}
Some(Ok(x)) => {
match x.file_type() {
Ok(ft) => {
let p = x.path().into_boxed_path();
return Some(Ok((if ft.is_dir() {
self.dirs.push(p.clone());
Some(true)
} else if ft.is_file() {
Some(false)
} else {
None
}, p)))
}
Err(e) => e
}
},
Some(Err(e)) => e
};
Some(Err(e))
fn check_dir_entry(de: walkdir::Result<walkdir::DirEntry>) -> io::Result<(Option<bool>, Box<Path>)> {
match de {
Err(e) => Err(e.into()),
Ok(de) => {
let ft = de.file_type();
let p = de.into_path().into_boxed_path();
Ok((if ft.is_dir() {
Some(true)
} else if ft.is_file() {
Some(false)
} else {
None
}, p))
}
}
}
26 changes: 23 additions & 3 deletions src/bin/mc-repack/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use mc_repack_core::{cfg, entry::{self, EntryReader, EntryReaderSpec, EntrySaver

mod cli_args;
mod config;
mod rrd;

type Error_ = anyhow::Error;
type Result_<T> = Result<T, Error_>;
Expand Down Expand Up @@ -185,14 +184,14 @@ type FileResult = std::io::Result<(Option<bool>, Box<Path>)>;

enum FilesIter {
Single(Option<FileResult>),
Dir(rrd::RecursiveReadDir)
Dir(std::vec::IntoIter<FileResult>)
}
impl FilesIter {
pub fn from_path(p: &Path) -> std::io::Result<(Box<Path>, Self)> {
let ft = p.metadata()?.file_type();
let p: Box<Path> = Box::from(p);
if ft.is_dir() {
Ok((p.clone(), Self::Dir(rrd::RecursiveReadDir::new(p))))
Ok((p.clone(), Self::Dir(walkdir::WalkDir::new(p).into_iter().map(|r| Ok(check_dir_entry(r?))).collect::<Vec<_>>().into_iter())))
} else if ft.is_file() {
let parent = p.parent().unwrap();
Ok((parent.into(), Self::Single(Some(Ok((Some(false), p))))))
Expand All @@ -216,4 +215,25 @@ impl Iterator for FilesIter {
Self::Dir(it) => it.size_hint()
}
}
}
impl ExactSizeIterator for FilesIter {
fn len(&self) -> usize {
match self {
Self::Single(Some(_)) => 1,
Self::Single(None) => 0,
Self::Dir(it) => it.len()
}
}
}

fn check_dir_entry(de: walkdir::DirEntry) -> (Option<bool>, Box<Path>) {
let ft = de.file_type();
let p = de.into_path().into_boxed_path();
(if ft.is_dir() {
Some(true)
} else if ft.is_file() {
Some(false)
} else {
None
}, p)
}
55 changes: 0 additions & 55 deletions src/bin/mc-repack/rrd.rs

This file was deleted.

0 comments on commit 2fb0207

Please sign in to comment.