diff options
Diffstat (limited to 'src/filters')
-rw-r--r-- | src/filters/values.rs | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/src/filters/values.rs b/src/filters/values.rs index 141aecd..df5b805 100644 --- a/src/filters/values.rs +++ b/src/filters/values.rs @@ -13,12 +13,14 @@ //! the two resulting values with the given comparison operator. use std::{ cmp::Ordering, + convert::TryFrom, fmt::{self, Debug}, }; use chrono::{DateTime, Duration, Utc}; +use evtclib::Agent; -use super::{log::LogFilter, Filter, Inclusion}; +use super::{log::LogFilter, player::PlayerFilter, Filter, Inclusion}; use crate::{EarlyLogResult, LogResult}; /// A producer for a given value. @@ -194,6 +196,44 @@ pub fn duration() -> Box<dyn Producer<Output = Duration>> { Box::new(DurationProducer) } +#[derive(Debug)] +struct PlayerCountProducer(Box<dyn PlayerFilter>); + +impl Producer for PlayerCountProducer { + type Output = u8; + + fn produce_early(&self, early_log: &EarlyLogResult) -> Option<Self::Output> { + let mut count = 0; + for agent in &early_log.evtc.agents { + if !agent.is_player() { + continue; + } + + let agent = Agent::try_from(agent); + if let Ok(agent) = agent { + let result = self.0.filter_early(&agent); + match result { + Inclusion::Include => count += 1, + Inclusion::Exclude => (), + Inclusion::Unknown => return None, + } + } else { + return None; + } + } + Some(count) + } + + fn produce(&self, log: &LogResult) -> Self::Output { + log.players.iter().filter(|p| self.0.filter(p)).count() as u8 + } +} + +/// A producer that counts the players matching the given filter. +pub fn player_count(filter: Box<dyn PlayerFilter>) -> Box<dyn Producer<Output = u8>> { + Box::new(PlayerCountProducer(filter)) +} + #[cfg(test)] mod tests { use super::*; |