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:
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "rust_util"
|
||||
version = "0.2.6"
|
||||
version = "0.3.0"
|
||||
authors = ["Hatter Jiang <jht5945@gmail.com>"]
|
||||
edition = "2018"
|
||||
description = "Hatter's Rust Util"
|
||||
|
||||
@@ -22,3 +22,8 @@ $ cargo update
|
||||
```
|
||||
|
||||
|
||||
## Update Log
|
||||
|
||||
* Jun 21, 2020 v0.3.0
|
||||
* add struct `JoinFilesReader`
|
||||
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
Reference in New Issue
Block a user