Skip to main content

captains_log/
parser.rs

1use regex::Regex;
2use std::fs::File;
3use std::io::{BufRead, BufReader, Lines, Result as IoResult};
4
5/// A simple LogParser with custom regex pattern
6pub 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    #[allow(clippy::needless_late_init)]
33    #[inline]
34    fn next(&mut self) -> Option<Self::Item> {
35        loop {
36            let line;
37            match self.lines.next() {
38                None => return None,
39                Some(Err(e)) => return Some(Err(e)),
40                Some(Ok(_line)) => {
41                    line = _line;
42                }
43            }
44            if let Some(caps) = self.re.captures(&line) {
45                let mut line_result = Vec::with_capacity(caps.len());
46                for m in caps.iter() {
47                    if let Some(mat) = m {
48                        line_result.push(mat.as_str().to_string());
49                    } else {
50                        line_result.push("".to_string());
51                    }
52                }
53                return Some(Ok(line_result));
54            }
55            // Ignore unrecognized format
56        }
57    }
58}