101 lines
2.1 KiB
Rust
101 lines
2.1 KiB
Rust
use std::{io, fs, path, cmp};
|
|
|
|
/// Creates an iterator over all blk .dat files
|
|
pub fn read_blk_dir<P>(path: P) -> Result<ReadBlkDir, io::Error> where P: AsRef<path::Path> {
|
|
let read_blk_dir = ReadBlkDir {
|
|
read_dir: try!(fs::read_dir(path)),
|
|
};
|
|
|
|
Ok(read_blk_dir)
|
|
}
|
|
|
|
pub struct ReadBlkDir {
|
|
read_dir: fs::ReadDir,
|
|
}
|
|
|
|
#[derive(PartialEq, Eq)]
|
|
pub struct BlkEntry {
|
|
pub path: path::PathBuf,
|
|
}
|
|
|
|
impl cmp::PartialOrd for BlkEntry {
|
|
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
|
|
cmp::PartialOrd::partial_cmp(&self.path, &other.path)
|
|
}
|
|
}
|
|
|
|
impl cmp::Ord for BlkEntry {
|
|
fn cmp(&self, other: &Self) -> cmp::Ordering {
|
|
cmp::Ord::cmp(&self.path, &other.path)
|
|
}
|
|
}
|
|
|
|
fn is_blk_file_name(file_name: &str) -> bool {
|
|
if file_name.len() != 12 || !file_name.starts_with("blk") || !file_name.ends_with(".dat") {
|
|
return false;
|
|
}
|
|
|
|
file_name[3..8].parse::<u32>().is_ok()
|
|
}
|
|
|
|
impl BlkEntry {
|
|
fn from_dir_entry(dir_entry: fs::DirEntry) -> Option<Self> {
|
|
match dir_entry.metadata() {
|
|
Err(_) => return None,
|
|
Ok(ref metadata) => {
|
|
if !metadata.is_file() {
|
|
return None;
|
|
}
|
|
}
|
|
}
|
|
|
|
match dir_entry.file_name().into_string() {
|
|
Err(_) => return None,
|
|
Ok(ref file_name) => {
|
|
if !is_blk_file_name(file_name) {
|
|
return None;
|
|
}
|
|
}
|
|
}
|
|
|
|
let entry = BlkEntry {
|
|
path: dir_entry.path(),
|
|
};
|
|
|
|
Some(entry)
|
|
}
|
|
}
|
|
|
|
impl Iterator for ReadBlkDir {
|
|
type Item = Result<BlkEntry, io::Error>;
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
let mut result = None;
|
|
while result.is_none() {
|
|
match self.read_dir.next() {
|
|
None => return None,
|
|
Some(Err(err)) => return Some(Err(err)),
|
|
Some(Ok(entry)) => {
|
|
result = BlkEntry::from_dir_entry(entry);
|
|
}
|
|
}
|
|
}
|
|
result.map(Ok)
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod test {
|
|
use super::is_blk_file_name;
|
|
|
|
#[test]
|
|
fn test_is_blk_file_name() {
|
|
assert!(is_blk_file_name("blk00000.dat"));
|
|
assert!(is_blk_file_name("blk00232.dat"));
|
|
assert!(!is_blk_file_name("blk0000.dat"));
|
|
assert!(!is_blk_file_name("blk00000.daw"));
|
|
assert!(!is_blk_file_name("blk00032.daw"));
|
|
assert!(!is_blk_file_name("blk000ff.dat"));
|
|
}
|
|
}
|