diff options
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 62 |
1 files changed, 49 insertions, 13 deletions
diff --git a/src/main.rs b/src/main.rs index 099262c..87ebbb0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,9 +9,10 @@ extern crate num_traits; extern crate rayon; extern crate regex; extern crate walkdir; +extern crate zip; use std::fs::File; -use std::io::{self, BufReader}; +use std::io::{self, BufReader, Read, Seek}; use std::path::PathBuf; use std::str::FromStr; @@ -220,6 +221,30 @@ fn try_from_str_simple_error<T: FromStr>(input: &str) -> Result<T, String> T::from_str(input).map_err(|_| format!("'{}' is an invalid value", input)) } + +enum ZipWrapper<R: Read + Seek> { + Raw(Option<R>), + Zipped(zip::ZipArchive<R>), +} + +impl<R: Read + Seek> ZipWrapper<R> { + pub fn raw(input: R) -> Self { + ZipWrapper::Raw(Some(input)) + } + + pub fn zipped(input: R) -> Self { + ZipWrapper::Zipped(zip::ZipArchive::new(input).unwrap()) + } + + pub fn get_stream<'a>(&'a mut self) -> Box<(dyn Read + 'a)> { + match *self { + ZipWrapper::Raw(ref mut o) => Box::new(o.take().unwrap()), + ZipWrapper::Zipped(ref mut z) => Box::new(z.by_index(0).unwrap()), + } + } +} + + fn main() { let opt = Opt::from_args(); @@ -258,8 +283,13 @@ fn grep(opt: &Opt) -> Result<(), RuntimeError> { let entry = entry?; s.spawn(move |_| { if is_log_file(&entry) { - if let Some(result) = search_log(&entry, opt).unwrap() { - output::output(io::stdout(), opt, &result).unwrap(); + let search = search_log(&entry, opt); + match search { + Ok(None) => (), + Ok(Some(result)) => output::output(io::stdout(), opt, &result).unwrap(), + Err(err) => { + debug!("Runtime error while scanning {:?}: {}", entry.path(), err); + } } } }); @@ -274,18 +304,25 @@ fn grep(opt: &Opt) -> Result<(), RuntimeError> { /// If the log doesn't match, returns `Ok(None)`. /// If there was a fatal error, returns `Err(..)`. fn search_log(entry: &DirEntry, opt: &Opt) -> Result<Option<LogResult>, RuntimeError> { - let mut input = BufReader::new(File::open(entry.path())?); - let raw = if entry + let file_stream = BufReader::new(File::open(entry.path())?); + let is_zip = entry .file_name() .to_str() .map(|n| n.ends_with(".zip") || n.ends_with(".zevtc")) - .unwrap_or(false) - { - evtclib::raw::parse_zip(&mut input) - } else { - evtclib::raw::parse_file(&mut input) + .unwrap_or(false); + let mut wrapper = match is_zip { + false => ZipWrapper::raw(file_stream), + true => ZipWrapper::zipped(file_stream), }; - let parsed = raw.ok().and_then(|m| evtclib::process(&m).ok()); + let mut stream = wrapper.get_stream(); + let partial = evtclib::raw::parser::parse_partial_file(&mut stream)?; + + if filters::filter_name(&partial, opt) == opt.invert { + return Ok(None) + } + + let raw = evtclib::raw::parser::finish_parsing(partial, &mut stream)?; + let parsed = evtclib::process(&raw).ok(); let log = if let Some(e) = parsed { e } else { @@ -295,8 +332,7 @@ fn search_log(entry: &DirEntry, opt: &Opt) -> Result<Option<LogResult>, RuntimeE let info = extract_info(entry, &log); - let take_log = filters::filter_name(&log, opt) == !opt.invert - && filters::filter_outcome(&info, opt) + let take_log = filters::filter_outcome(&info, opt) && filters::filter_weekday(&info, opt) && filters::filter_time(&info, opt); |