1use regex::Regex;
2use std::fs::File;
3use std::io::{BufRead, BufReader, Lines, Result as IoResult};
4
5pub struct LogParser {
7 reader: BufReader<File>,
8 re: Regex,
9}
10
11impl LogParser {
12 pub fn new(file_path: &str, re_pattern: &str, buf_size: usize) -> IoResult<Self> {
13 let f = File::open(file_path)?;
14 let reader = BufReader::with_capacity(buf_size, f);
15 let re = Regex::new(re_pattern).expect("regex pattern valid");
16 Ok(Self { reader, re })
17 }
18
19 pub fn lines(self) -> LogParserLineIter {
20 LogParserLineIter { lines: self.reader.lines(), re: self.re }
21 }
22}
23
24pub struct LogParserLineIter {
25 re: Regex,
26 lines: Lines<BufReader<File>>,
27}
28
29impl Iterator for LogParserLineIter {
30 type Item = IoResult<Vec<String>>;
31
32 #[inline]
33 fn next(&mut self) -> Option<Self::Item> {
34 loop {
35 let line;
36 match self.lines.next() {
37 None => return None,
38 Some(Err(e)) => return Some(Err(e)),
39 Some(Ok(_line)) => {
40 line = _line;
41 }
42 }
43 if let Some(caps) = self.re.captures(&line) {
44 let mut line_result = Vec::with_capacity(caps.len());
45 for m in caps.iter() {
46 if let Some(mat) = m {
47 line_result.push(mat.as_str().to_string());
48 } else {
49 line_result.push("".to_string());
50 }
51 }
52 return Some(Ok(line_result));
53 }
54 }
56 }
57}