diff options
author | Daniel <kingdread@gmx.de> | 2020-04-15 15:01:10 +0200 |
---|---|---|
committer | Daniel <kingdread@gmx.de> | 2020-04-15 15:01:10 +0200 |
commit | 7881ba85ff40f3d22237ef903c7241b56aa9c185 (patch) | |
tree | 975ad07930052191766f21515729c2880bbbc2e2 /src/csl.rs | |
parent | 3c429432382dfad6d4ac97349c96e4a4eb292089 (diff) | |
download | raidgrep-7881ba85ff40f3d22237ef903c7241b56aa9c185.tar.gz raidgrep-7881ba85ff40f3d22237ef903c7241b56aa9c185.tar.bz2 raidgrep-7881ba85ff40f3d22237ef903c7241b56aa9c185.zip |
new filter pipeline
This is the groundwork for introducing more complex filter queries like
`find` has. Filters can be arbitrarily combined with and/or/not and
support an "early filter" mode.
So far, the filters have been translated pretty mechanically to match
the current command line arguments, so now new syntax has been
introduced.
The NameFilter is not yet in its final version. The goal is to support
something like PlayerAll/PlayerExists and have a PlayerFilter that works
on single players instead of the complete log, but that might introduce
some code duplication as we then need a PlayerFilterAnd, PlayerFilterOr,
...
Some digging has to be done into whether we can reduce that duplication
without devolving into madness or resorting to macros. Maybe some
type-level generic hackery could be done? Maybe an enum instead of
dynamic traits should be used, at least for the base functions?
Diffstat (limited to 'src/csl.rs')
-rw-r--r-- | src/csl.rs | 34 |
1 files changed, 27 insertions, 7 deletions
@@ -1,14 +1,14 @@ use std::collections::HashSet; +use std::fmt; use std::hash::Hash; use std::str::FromStr; -use std::fmt; -use super::{SearchField, FightOutcome}; +use super::{FightOutcome, SearchField}; use chrono::Weekday; use evtclib::statistics::gamedata::Boss; pub trait Variants: Copy { - type Output: Iterator<Item=Self>; + type Output: Iterator<Item = Self>; fn variants() -> Self::Output; } @@ -79,18 +79,21 @@ impl<E: fmt::Display> fmt::Display for ParseError<E> { } impl<T> FromStr for CommaSeparatedList<T> - where T: FromStr + Variants + Hash + Eq + fmt::Debug +where + T: FromStr + Variants + Hash + Eq + fmt::Debug, { type Err = ParseError<T::Err>; fn from_str(input: &str) -> Result<Self, Self::Err> { if input == "*" { - Ok(CommaSeparatedList { values: T::variants().collect() }) + Ok(CommaSeparatedList { + values: T::variants().collect(), + }) } else if input.starts_with(NEGATOR) { let no_csl = CommaSeparatedList::from_str(&input[1..])?; let all_values = T::variants().collect::<HashSet<_>>(); Ok(CommaSeparatedList { - values: all_values.difference(&no_csl.values).cloned().collect() + values: all_values.difference(&no_csl.values).cloned().collect(), }) } else { let parts = input.split(DELIMITER); @@ -104,9 +107,26 @@ impl<T> FromStr for CommaSeparatedList<T> } impl<T> CommaSeparatedList<T> - where T: Hash + Eq + fmt::Debug +where + T: Hash + Eq + fmt::Debug, { pub fn contains(&self, value: &T) -> bool { self.values.contains(value) } + + pub fn values(&self) -> &HashSet<T> { + &self.values + } +} + +// We allow implicit hasher because then it's a zero-cost conversion, as we're just unwrapping the +// values. +#[allow(clippy::implicit_hasher)] +impl<T> From<CommaSeparatedList<T>> for HashSet<T> +where + T: Hash + Eq + fmt::Debug, +{ + fn from(csl: CommaSeparatedList<T>) -> Self { + csl.values + } } |