aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/fexpr/grammar.lalrpop3
-rw-r--r--src/fexpr/mod.rs2
-rw-r--r--src/filters/log.rs19
-rw-r--r--src/filters/player.rs9
-rw-r--r--src/main.rs21
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<PartialEvtc, LogResult>;
+pub trait LogFilter = Filter<EarlyLogResult, LogResult>;
#[derive(Debug, Clone)]
struct BossFilter(HashSet<Boss>);
-impl Filter<PartialEvtc, LogResult> for BossFilter {
- fn filter_early(&self, partial_evtc: &PartialEvtc) -> Inclusion {
- let boss = Boss::from_u16(partial_evtc.header.combat_id);
+impl Filter<EarlyLogResult, LogResult> 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<Boss>) -> Box<dyn LogFilter> {
#[derive(Debug, Clone)]
struct OutcomeFilter(HashSet<FightOutcome>);
-impl Filter<PartialEvtc, LogResult> for OutcomeFilter {
+impl Filter<EarlyLogResult, LogResult> for OutcomeFilter {
fn filter(&self, log: &LogResult) -> bool {
self.0.contains(&log.outcome)
}
@@ -76,7 +75,7 @@ pub fn wipe() -> Box<dyn LogFilter> {
#[derive(Debug, Clone)]
struct WeekdayFilter(HashSet<Weekday>);
-impl Filter<PartialEvtc, LogResult> for WeekdayFilter {
+impl Filter<EarlyLogResult, LogResult> for WeekdayFilter {
fn filter(&self, log: &LogResult) -> bool {
self.0.contains(&log.time.weekday())
}
@@ -90,7 +89,7 @@ pub fn weekday(weekdays: HashSet<Weekday>) -> Box<dyn LogFilter> {
#[derive(Debug, Clone)]
struct TimeFilter(Option<DateTime<Utc>>, Option<DateTime<Utc>>);
-impl Filter<PartialEvtc, LogResult> for TimeFilter {
+impl Filter<EarlyLogResult, LogResult> 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<Agent, Player>;
#[derive(Debug)]
struct AllPlayers(Box<dyn PlayerFilter>);
-impl Filter<PartialEvtc, LogResult> for AllPlayers {
- fn filter_early(&self, partial_evtc: &PartialEvtc) -> Inclusion {
+impl Filter<EarlyLogResult, LogResult> 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<Option<LogResu
let mut stream = wrapper.get_stream();
let partial = evtclib::raw::parser::parse_partial_file(&mut stream)?;
- let early_ok = filter.filter_early(&partial);
+ let early_log = EarlyLogResult {
+ log_file: entry.path().to_owned(),
+ evtc: partial,
+ };
+ let early_ok = filter.filter_early(&early_log);
+ let partial = early_log.evtc;
if early_ok == Inclusion::Exclude {
return Ok(None);