diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/fexpr/grammar.lalrpop | 26 | ||||
| -rw-r--r-- | src/filters/log.rs | 99 | ||||
| -rw-r--r-- | src/filters/mod.rs | 14 | ||||
| -rw-r--r-- | src/filters/player.rs | 23 | ||||
| -rw-r--r-- | src/main.rs | 3 | 
5 files changed, 97 insertions, 68 deletions
| diff --git a/src/fexpr/grammar.lalrpop b/src/fexpr/grammar.lalrpop index caaaf7f..d8f64fa 100644 --- a/src/fexpr/grammar.lalrpop +++ b/src/fexpr/grammar.lalrpop @@ -44,19 +44,19 @@ Negation<T>: T = {  }  LogPredicate: Box<dyn filters::log::LogFilter> = { -    "-success" => filters::log::OutcomeFilter::success(), -    "-wipe" => filters::log::OutcomeFilter::wipe(), -    "-outcome" <Comma<FightOutcome>> => filters::log::OutcomeFilter::new(<>), +    "-success" => filters::log::success(), +    "-wipe" => filters::log::wipe(), +    "-outcome" <Comma<FightOutcome>> => filters::log::outcome(<>), -    "-weekday" <Comma<Weekday>> => filters::log::WeekdayFilter::new(<>), -    "-before" <Date> => filters::log::TimeFilter::new(None, Some(<>)), -    "-after" <Date> => filters::log::TimeFilter::new(Some(<>), None), +    "-weekday" <Comma<Weekday>> => filters::log::weekday(<>), +    "-before" <Date> => filters::log::before(<>), +    "-after" <Date> => filters::log::after(<>), -    "-boss" <Comma<Boss>> => filters::log::BossFilter::new(<>), +    "-boss" <Comma<Boss>> => filters::log::boss(<>),      "-player" <Regex> => filters::player::any( -            filters::player::NameFilter::new(SearchField::Character, <>.clone()) -            | filters::player::NameFilter::new(SearchField::Account, <>) +            filters::player::character(<>.clone()) +            | filters::player::account(<>)          ),      "all" "(" "player" ":" <PlayerFilter> ")" => filters::player::all(<>), @@ -67,11 +67,11 @@ LogPredicate: Box<dyn filters::log::LogFilter> = {  }  PlayerPredicate: Box<dyn filters::player::PlayerFilter> = { -    "-character" <Regex> => filters::player::NameFilter::new(SearchField::Character, <>), -    "-account" <Regex> => filters::player::NameFilter::new(SearchField::Account, <>), +    "-character" <Regex> => filters::player::character(<>), +    "-account" <Regex> => filters::player::account(<>),      "-name" <Regex> => -        filters::player::NameFilter::new(SearchField::Account, <>.clone()) -        | filters::player::NameFilter::new(SearchField::Character, <>), +        filters::player::account(<>.clone()) +        | filters::player::character(<>),      "(" <PlayerFilter> ")",  } diff --git a/src/filters/log.rs b/src/filters/log.rs index 8b84bf3..8d4e0b5 100644 --- a/src/filters/log.rs +++ b/src/filters/log.rs @@ -19,13 +19,7 @@ use num_traits::FromPrimitive as _;  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)) -    } -} +struct BossFilter(HashSet<Boss>);  impl Filter<PartialEvtc, LogResult> for BossFilter {      fn filter_early(&self, partial_evtc: &PartialEvtc) -> Inclusion { @@ -40,26 +34,14 @@ impl Filter<PartialEvtc, LogResult> for BossFilter {      }  } -#[derive(Debug, Clone)] -pub struct OutcomeFilter(HashSet<FightOutcome>); - -impl OutcomeFilter { -    pub fn new(outcomes: HashSet<FightOutcome>) -> Box<dyn LogFilter> { -        Box::new(OutcomeFilter(outcomes)) -    } +/// 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)) +} -    pub fn success() -> Box<dyn LogFilter> { -        let mut outcomes = HashSet::new(); -        outcomes.insert(FightOutcome::Success); -        Self::new(outcomes) -    } -    pub fn wipe() -> Box<dyn LogFilter> { -        let mut outcomes = HashSet::new(); -        outcomes.insert(FightOutcome::Wipe); -        Self::new(outcomes) -    } -} +#[derive(Debug, Clone)] +struct OutcomeFilter(HashSet<FightOutcome>);  impl Filter<PartialEvtc, LogResult> for OutcomeFilter {      fn filter(&self, log: &LogResult) -> bool { @@ -67,30 +49,49 @@ impl Filter<PartialEvtc, LogResult> for OutcomeFilter {      }  } -#[derive(Debug, Clone)] -pub struct WeekdayFilter(HashSet<Weekday>); +/// 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)) +} -impl WeekdayFilter { -    pub fn new(weekdays: HashSet<Weekday>) -> Box<dyn LogFilter> { -        Box::new(WeekdayFilter(weekdays)) -    } +/// 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())      }  } -#[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)) -    } +/// 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 { @@ -105,3 +106,25 @@ impl Filter<PartialEvtc, LogResult> for TimeFilter {          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)) +} diff --git a/src/filters/mod.rs b/src/filters/mod.rs index 3d0868b..162b6f8 100644 --- a/src/filters/mod.rs +++ b/src/filters/mod.rs @@ -1,4 +1,3 @@ -#![allow(clippy::new_ret_no_self)]  use std::{fmt, ops};  use num_derive::FromPrimitive; @@ -74,13 +73,7 @@ pub trait Filter<Early, Late>: Send + Sync + fmt::Debug {  }  #[derive(Debug, Clone, Copy)] -pub struct Const(pub bool); - -impl Const { -    pub fn new<E, L>(output: bool) -> Box<dyn Filter<E, L>> { -        Box::new(Const(output)) -    } -} +struct Const(pub bool);  impl<E, L> Filter<E, L> for Const {      fn filter_early(&self, _: &E) -> Inclusion { @@ -92,6 +85,11 @@ impl<E, L> Filter<E, L> for Const {      }  } +/// Construct a `Filter` that always returns a fixed value. +pub fn constant<E, L>(output: bool) -> Box<dyn Filter<E, L>> { +    Box::new(Const(output)) +} +  struct AndFilter<E, L>(Box<dyn Filter<E, L>>, Box<dyn Filter<E, L>>);  impl<E, L> Filter<E, L> for AndFilter<E, L> { diff --git a/src/filters/player.rs b/src/filters/player.rs index 8f9196a..4daeb22 100644 --- a/src/filters/player.rs +++ b/src/filters/player.rs @@ -64,13 +64,7 @@ pub fn any(player_filter: Box<dyn PlayerFilter>) -> Box<dyn LogFilter> {  ///  /// The given SearchField determines in which field something should be searched.  #[derive(Debug, Clone)] -pub struct NameFilter(SearchField, Regex); - -impl NameFilter { -    pub fn new(field: SearchField, regex: Regex) -> Box<dyn PlayerFilter> { -        Box::new(NameFilter(field, regex)) -    } -} +struct NameFilter(SearchField, Regex);  impl Filter<Agent, Player> for NameFilter {      fn filter_early(&self, agent: &Agent) -> Inclusion { @@ -108,3 +102,18 @@ impl Filter<Agent, Player> for NameFilter {          }      }  } + +/// Construct a `PlayerFilter` that searches the given `field` with the given `regex`. +pub fn name(field: SearchField, regex: Regex) -> Box<dyn PlayerFilter> { +    Box::new(NameFilter(field, regex)) +} + +/// Construct a `PlayerFilter` that searches the character name with the given `regex`. +pub fn character(regex: Regex) -> Box<dyn PlayerFilter> { +    name(SearchField::Character, regex) +} + +/// Construct a `PlayerFilter` that searches the account name with the given `regex`. +pub fn account(regex: Regex) -> Box<dyn PlayerFilter> { +    name(SearchField::Account, regex) +} diff --git a/src/main.rs b/src/main.rs index 3164bd4..50dcf8d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -266,8 +266,7 @@ fn single(opt: &Opt) -> Result<()> {              let maybe_regex = Regex::new(line);              if let Ok(rgx) = maybe_regex {                  let filter = filters::player::any( -                    filters::player::NameFilter::new(SearchField::Account, rgx.clone()) -                        | filters::player::NameFilter::new(SearchField::Character, rgx), +                    filters::player::account(rgx.clone()) | filters::player::character(rgx),                  );                  return grep(opt, &*filter);              } | 
