1
0
mirror of https://github.com/jht5945/rust_util.git synced 2025-12-27 15:40:03 +08:00

v0.3.0 add JoinFilesReader

This commit is contained in:
2020-06-21 13:19:50 +08:00
parent 0ebd4e5630
commit 328f4c503f
3 changed files with 71 additions and 2 deletions

View File

@@ -1,7 +1,8 @@
use std::{
env,
fs,
fs::{self, File},
io::{Lines, BufReader},
path::{Path, PathBuf},
};
@@ -13,6 +14,69 @@ use super::{
XResult,
};
pub struct JoinFilesReader {
files: Vec<String>,
file_ptr: usize,
file_lines: Option<Box<Lines<BufReader<File>>>>,
}
fn open_file_as_lines(f: &str) -> XResult<Lines<BufReader<File>>> {
let f = File::open(&f)?;
let br = BufReader::new(f);
use std::io::BufRead;
Ok(br.lines())
}
impl JoinFilesReader {
pub fn new(fns: &[&str]) -> XResult<Self> {
let mut files: Vec<String> = vec![];
for f in fns {
files.push(f.to_string());
}
let file_ptr = 0;
let mut file_lines = None;
if !files.is_empty() {
file_lines = Some(Box::new(open_file_as_lines(&files[0])?));
}
Ok(Self {
files,
file_ptr,
file_lines,
})
}
}
impl Iterator for JoinFilesReader {
type Item = XResult<String>;
fn next(&mut self) -> Option<Self::Item> {
loop {
match self.file_lines {
Some(ref mut ln) => match ln.next() {
Some(r) => return Some(r.map_err(|e| e.into())),
None => {
self.file_ptr += 1;
self.file_lines = None;
if self.file_ptr >= self.files.len() {
return None;
} else {
// if open file failed, will not continue read files
self.file_lines = Some(Box::new(match open_file_as_lines(&self.files[self.file_ptr]) {
Ok(ln) => ln, Err(e) => return Some(Err(e)),
}));
}
},
},
None => return None,
}
if self.file_ptr >= self.files.len() {
return None;
}
}
}
}
pub fn locate_file(files: &[String]) -> Option<PathBuf> {
for f in files {
match PathBuf::from(&resolve_file_path(f)) {