aboutsummaryrefslogtreecommitdiff
path: root/src/filters/log.rs
diff options
context:
space:
mode:
authorDaniel <kingdread@gmx.de>2020-04-26 11:45:37 +0200
committerDaniel <kingdread@gmx.de>2020-04-26 11:45:37 +0200
commit13053073e3336b8e6ffefd6a056d159239550be7 (patch)
tree63544e8764b55563a48d3f9fd530b0381f42a277 /src/filters/log.rs
parent3c429432382dfad6d4ac97349c96e4a4eb292089 (diff)
parent9bbd5db2a6caae10f0ab2cf2625fbc34485a4ce9 (diff)
downloadraidgrep-13053073e3336b8e6ffefd6a056d159239550be7.tar.gz
raidgrep-13053073e3336b8e6ffefd6a056d159239550be7.tar.bz2
raidgrep-13053073e3336b8e6ffefd6a056d159239550be7.zip
Merge branch 'new-filters'
The new filter system (includes both the internal rewrite and the command line parsing) is now being included in master. This gives a lot more flexibility.
Diffstat (limited to 'src/filters/log.rs')
-rw-r--r--src/filters/log.rs130
1 files changed, 130 insertions, 0 deletions
diff --git a/src/filters/log.rs b/src/filters/log.rs
new file mode 100644
index 0000000..8d4e0b5
--- /dev/null
+++ b/src/filters/log.rs
@@ -0,0 +1,130 @@
+//! This module contains specific filters that operate on log files.
+//!
+//! 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},
+ Filter, Inclusion,
+};
+
+use std::collections::HashSet;
+
+use evtclib::raw::parser::PartialEvtc;
+use evtclib::statistics::gamedata::Boss;
+
+use chrono::{Datelike, NaiveDateTime};
+use num_traits::FromPrimitive as _;
+
+/// Filter trait used for filters that operate on complete logs.
+pub trait LogFilter = Filter<PartialEvtc, 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);
+ boss.map(|b| self.0.contains(&b).into())
+ .unwrap_or(Inclusion::Include)
+ }
+
+ fn filter(&self, log: &LogResult) -> bool {
+ let boss = Boss::from_u16(log.boss_id);
+ boss.map(|b| self.0.contains(&b)).unwrap_or(false)
+ }
+}
+
+/// A `LogFilter` that only accepts logs with one of the given bosses.
+pub fn boss(bosses: HashSet<Boss>) -> Box<dyn LogFilter> {
+ Box::new(BossFilter(bosses))
+}
+
+
+#[derive(Debug, Clone)]
+struct OutcomeFilter(HashSet<FightOutcome>);
+
+impl Filter<PartialEvtc, LogResult> for OutcomeFilter {
+ fn filter(&self, log: &LogResult) -> bool {
+ self.0.contains(&log.outcome)
+ }
+}
+
+/// A `LogFilter` that only accepts logs with one of the given outcomes.
+///
+/// See also [`success`][success] and [`wipe`][wipe].
+pub fn outcome(outcomes: HashSet<FightOutcome>) -> Box<dyn LogFilter> {
+ Box::new(OutcomeFilter(outcomes))
+}
+
+/// A `LogFilter` that only accepts successful logs.
+///
+/// See also [`outcome`][outcome] and [`wipe`][wipe].
+pub fn success() -> Box<dyn LogFilter> {
+ let mut outcomes = HashSet::new();
+ outcomes.insert(FightOutcome::Success);
+ outcome(outcomes)
+}
+
+/// A `LogFilter` that only accepts failed logs.
+///
+/// See also [`outcome`][outcome] and [`success`][wipe].
+pub fn wipe() -> Box<dyn LogFilter> {
+ let mut outcomes = HashSet::new();
+ outcomes.insert(FightOutcome::Wipe);
+ outcome(outcomes)
+}
+
+#[derive(Debug, Clone)]
+struct WeekdayFilter(HashSet<Weekday>);
+
+impl Filter<PartialEvtc, LogResult> for WeekdayFilter {
+ fn filter(&self, log: &LogResult) -> bool {
+ self.0.contains(&log.time.weekday())
+ }
+}
+
+/// A `LogFilter` that only accepts logs if they were done on one of the given weekdays.
+pub fn weekday(weekdays: HashSet<Weekday>) -> Box<dyn LogFilter> {
+ Box::new(WeekdayFilter(weekdays))
+}
+
+
+#[derive(Debug, Clone)]
+struct TimeFilter(Option<NaiveDateTime>, Option<NaiveDateTime>);
+
+impl Filter<PartialEvtc, LogResult> for TimeFilter {
+ fn filter(&self, log: &LogResult) -> bool {
+ let after_ok = match self.0 {
+ Some(time) => time <= log.time,
+ None => true,
+ };
+ let before_ok = match self.1 {
+ Some(time) => time >= log.time,
+ None => true,
+ };
+
+ after_ok && before_ok
+ }
+}
+
+/// A `LogFilter` that only accepts logs in the given time frame.
+///
+/// If a bound is not given, -Infinity is assumed for the lower bound, and Infinity for the upper
+/// bound.
+pub fn time(lower: Option<NaiveDateTime>, upper: Option<NaiveDateTime>) -> Box<dyn LogFilter> {
+ Box::new(TimeFilter(lower, upper))
+}
+
+/// A `LogFilter` that only accepts logs after the given date.
+///
+/// Also see [`time`][time] and [`before`][before].
+pub fn after(when: NaiveDateTime) -> Box<dyn LogFilter> {
+ time(Some(when), None)
+}
+
+/// A `LogFilter` that only accepts logs before the given date.
+///
+/// Also see [`time`][time] and [`after`][after].
+pub fn before(when: NaiveDateTime) -> Box<dyn LogFilter> {
+ time(None, Some(when))
+}