aboutsummaryrefslogtreecommitdiff
path: root/src/filters/log.rs
diff options
context:
space:
mode:
authorDaniel <kingdread@gmx.de>2020-04-17 15:18:20 +0200
committerDaniel <kingdread@gmx.de>2020-04-17 15:18:20 +0200
commitba491c8a5f6c8c2fa86b12dacf9d80f92da9168a (patch)
treee448ef79962fa06f0653d01e0716c8a8a14baa56 /src/filters/log.rs
parentc381bfd0972d8f8e080c74d63df66486e514f35f (diff)
downloadraidgrep-ba491c8a5f6c8c2fa86b12dacf9d80f92da9168a.tar.gz
raidgrep-ba491c8a5f6c8c2fa86b12dacf9d80f92da9168a.tar.bz2
raidgrep-ba491c8a5f6c8c2fa86b12dacf9d80f92da9168a.zip
split off player filters and log filters
As it turns out, we can easily re-use the existing Filter machinery to generalize over LogFilters (which operate on LogResults) and PlayerFilters (which operate on Players). The feature trait_aliases is not strictly needed but makes the function signatures a bit nicer and easier to read, and it reduces the chances of an error (e.g. by using Filter<&PartialEvtc, ...>).
Diffstat (limited to 'src/filters/log.rs')
-rw-r--r--src/filters/log.rs95
1 files changed, 95 insertions, 0 deletions
diff --git a/src/filters/log.rs b/src/filters/log.rs
new file mode 100644
index 0000000..ded4c44
--- /dev/null
+++ b/src/filters/log.rs
@@ -0,0 +1,95 @@
+//! 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)]
+pub struct BossFilter(HashSet<Boss>);
+
+impl BossFilter {
+ pub fn new(bosses: HashSet<Boss>) -> Box<dyn LogFilter> {
+ Box::new(BossFilter(bosses))
+ }
+}
+
+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)
+ }
+}
+
+#[derive(Debug, Clone)]
+pub struct OutcomeFilter(HashSet<FightOutcome>);
+
+impl OutcomeFilter {
+ pub fn new(outcomes: HashSet<FightOutcome>) -> Box<dyn LogFilter> {
+ Box::new(OutcomeFilter(outcomes))
+ }
+}
+
+impl Filter<PartialEvtc, LogResult> for OutcomeFilter {
+ fn filter(&self, log: &LogResult) -> bool {
+ self.0.contains(&log.outcome)
+ }
+}
+
+#[derive(Debug, Clone)]
+pub struct WeekdayFilter(HashSet<Weekday>);
+
+impl WeekdayFilter {
+ pub fn new(weekdays: HashSet<Weekday>) -> Box<dyn LogFilter> {
+ Box::new(WeekdayFilter(weekdays))
+ }
+}
+
+impl Filter<PartialEvtc, LogResult> for WeekdayFilter {
+ fn filter(&self, log: &LogResult) -> bool {
+ self.0.contains(&log.time.weekday())
+ }
+}
+
+#[derive(Debug, Clone)]
+pub struct TimeFilter(Option<NaiveDateTime>, Option<NaiveDateTime>);
+
+impl TimeFilter {
+ pub fn new(after: Option<NaiveDateTime>, before: Option<NaiveDateTime>) -> Box<dyn LogFilter> {
+ Box::new(TimeFilter(after, before))
+ }
+}
+
+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
+ }
+}