From 5f765b749f793b2866262546d28ff138a5654dfc Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 1 May 2020 13:29:38 +0200 Subject: change LogFilter to take EarlyLogResult This allows us to attach some additional metadata that is not found in the PartialEvtc otherwise, such as the file name. --- src/fexpr/grammar.lalrpop | 3 +-- src/fexpr/mod.rs | 2 +- src/filters/log.rs | 19 +++++++++---------- src/filters/player.rs | 9 ++++----- src/main.rs | 21 +++++++++++++++++++-- 5 files changed, 34 insertions(+), 20 deletions(-) diff --git a/src/fexpr/grammar.lalrpop b/src/fexpr/grammar.lalrpop index 8674b84..4cb1849 100644 --- a/src/fexpr/grammar.lalrpop +++ b/src/fexpr/grammar.lalrpop @@ -4,13 +4,12 @@ use super::{ FightOutcome, filters, SearchField, - Weekday, }; use evtclib::Boss; use std::collections::HashSet; use lalrpop_util::ParseError; -use chrono::{DateTime, Local, TimeZone, Utc}; +use chrono::{DateTime, Local, TimeZone, Utc, Weekday}; use regex::Regex; grammar; diff --git a/src/fexpr/mod.rs b/src/fexpr/mod.rs index 5610aba..391b739 100644 --- a/src/fexpr/mod.rs +++ b/src/fexpr/mod.rs @@ -3,7 +3,7 @@ //! This module contains methods to parse a given string into an abstract filter tree, check its //! type and convert it to a [`Filter`][super::filters::Filter]. // Make it available in the grammar mod. -use super::{filters, FightOutcome, SearchField, Weekday}; +use super::{filters, FightOutcome, SearchField}; use std::{error, fmt}; diff --git a/src/filters/log.rs b/src/filters/log.rs index 2d2fc37..60e6912 100644 --- a/src/filters/log.rs +++ b/src/filters/log.rs @@ -3,27 +3,26 @@ //! This is the "base unit", as each file corresponds to one log. Filters on other items (such as //! players) have to be lifted into log filters first. use super::{ - super::{FightOutcome, LogResult, Weekday}, + super::{EarlyLogResult, FightOutcome, LogResult}, Filter, Inclusion, }; use std::collections::HashSet; -use evtclib::raw::parser::PartialEvtc; use evtclib::Boss; -use chrono::{DateTime, Datelike, Utc}; +use chrono::{DateTime, Datelike, Utc, Weekday}; use num_traits::FromPrimitive as _; /// Filter trait used for filters that operate on complete logs. -pub trait LogFilter = Filter; +pub trait LogFilter = Filter; #[derive(Debug, Clone)] struct BossFilter(HashSet); -impl Filter for BossFilter { - fn filter_early(&self, partial_evtc: &PartialEvtc) -> Inclusion { - let boss = Boss::from_u16(partial_evtc.header.combat_id); +impl Filter for BossFilter { + fn filter_early(&self, early_log: &EarlyLogResult) -> Inclusion { + let boss = Boss::from_u16(early_log.evtc.header.combat_id); boss.map(|b| self.0.contains(&b).into()) .unwrap_or(Inclusion::Exclude) } @@ -42,7 +41,7 @@ pub fn boss(bosses: HashSet) -> Box { #[derive(Debug, Clone)] struct OutcomeFilter(HashSet); -impl Filter for OutcomeFilter { +impl Filter for OutcomeFilter { fn filter(&self, log: &LogResult) -> bool { self.0.contains(&log.outcome) } @@ -76,7 +75,7 @@ pub fn wipe() -> Box { #[derive(Debug, Clone)] struct WeekdayFilter(HashSet); -impl Filter for WeekdayFilter { +impl Filter for WeekdayFilter { fn filter(&self, log: &LogResult) -> bool { self.0.contains(&log.time.weekday()) } @@ -90,7 +89,7 @@ pub fn weekday(weekdays: HashSet) -> Box { #[derive(Debug, Clone)] struct TimeFilter(Option>, Option>); -impl Filter for TimeFilter { +impl Filter for TimeFilter { fn filter(&self, log: &LogResult) -> bool { let after_ok = match self.0 { Some(time) => time <= log.time, diff --git a/src/filters/player.rs b/src/filters/player.rs index 7258bd7..3af2be2 100644 --- a/src/filters/player.rs +++ b/src/filters/player.rs @@ -3,14 +3,13 @@ //! Additionally, it provides methods to lift a player filter to a log filter with [`any`][any] and //! [`all`][all]. use super::{ - super::{guilds, LogResult, Player, SearchField}, + super::{guilds, EarlyLogResult, LogResult, Player, SearchField}, log::LogFilter, Filter, Inclusion, }; use std::convert::TryFrom; -use evtclib::raw::parser::PartialEvtc; use evtclib::{Agent, AgentKind}; use regex::Regex; @@ -25,10 +24,10 @@ pub trait PlayerFilter = Filter; #[derive(Debug)] struct AllPlayers(Box); -impl Filter for AllPlayers { - fn filter_early(&self, partial_evtc: &PartialEvtc) -> Inclusion { +impl Filter for AllPlayers { + fn filter_early(&self, early_log: &EarlyLogResult) -> Inclusion { let mut result = Inclusion::Include; - for agent in &partial_evtc.agents { + for agent in &early_log.evtc.agents { if !agent.is_player() { continue; } diff --git a/src/main.rs b/src/main.rs index db2a5e7..33b3c45 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,7 +7,7 @@ use std::path::PathBuf; use std::str::FromStr; use anyhow::{anyhow, Error, Result}; -use chrono::{DateTime, TimeZone, Utc, Weekday}; +use chrono::{DateTime, TimeZone, Utc}; use colored::Colorize; use itertools::Itertools; use log::debug; @@ -16,6 +16,7 @@ use rustyline::Editor; use structopt::StructOpt; use walkdir::{DirEntry, WalkDir}; +use evtclib::raw::parser::PartialEvtc; use evtclib::{EliteSpec, EventKind, Log, Profession}; mod fexpr; @@ -155,6 +156,17 @@ pub enum FightOutcome { Wipe, } +/// A stripped version of [`LogResult`][LogResult] that is available early in the parsing process. +/// +/// This can be used by filters to filter out logs early, before they will be fully parsed. +#[derive(Debug, Clone)] +pub struct EarlyLogResult { + /// The path to the log file. + log_file: PathBuf, + /// The partially parsed evtc. + evtc: PartialEvtc, +} + impl FromStr for FightOutcome { type Err = &'static str; @@ -368,7 +380,12 @@ fn search_log(entry: &DirEntry, filter: &dyn LogFilter) -> Result