1use crate::event::Event;
11
12pub trait EventObserver {
13 fn on_event(&mut self, event: &Event);
14}
15
16#[derive(Debug, Default, Clone)]
17pub struct SeasonTelemetry {
18 pub matches: u32,
19 pub goals: u32,
20 pub home_wins: u32,
21 pub draws: u32,
22 pub away_wins: u32,
23 pub scoreline_counts: std::collections::BTreeMap<(u8, u8), u32>,
24}
25
26impl SeasonTelemetry {
27 pub fn goals_per_match(&self) -> f64 {
28 if self.matches == 0 {
29 return 0.0;
30 }
31 self.goals as f64 / self.matches as f64
32 }
33
34 pub fn home_win_rate(&self) -> f64 {
35 if self.matches == 0 {
36 return 0.0;
37 }
38 self.home_wins as f64 / self.matches as f64
39 }
40}
41
42impl EventObserver for SeasonTelemetry {
43 fn on_event(&mut self, event: &Event) {
44 if let Event::MatchPlayed {
45 home_goals,
46 away_goals,
47 ..
48 } = event
49 {
50 self.matches += 1;
51 self.goals += (*home_goals + *away_goals) as u32;
52 match home_goals.cmp(away_goals) {
53 std::cmp::Ordering::Greater => self.home_wins += 1,
54 std::cmp::Ordering::Equal => self.draws += 1,
55 std::cmp::Ordering::Less => self.away_wins += 1,
56 }
57 *self
58 .scoreline_counts
59 .entry((*home_goals, *away_goals))
60 .or_default() += 1;
61 }
62 }
63}