aboutsummaryrefslogtreecommitdiff
path: root/src/filters/values.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/filters/values.rs')
-rw-r--r--src/filters/values.rs42
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::*;