coa_website/
stats.rs

1use std::collections::HashMap;
2
3use serde::Serialize;
4
5/// Server statistics
6#[derive(Debug, Default, Serialize)]
7pub struct Stats {
8    total_requests: u64,
9    status_counts: HashMap<u16, u64>
10}
11
12impl Stats {
13    /// Creates a new empty stats tracker.
14    pub fn new() -> Self {
15        Self {
16            total_requests: 0,
17            status_counts: HashMap::new(),
18        }
19    }
20
21    /// Increments the total request count and the counter for a specific status code.
22    pub fn record(&mut self, status_code: u16) {
23        self.total_requests += 1;
24        *self.status_counts.entry(status_code).or_insert(0) += 1;
25    }
26
27    /// Returns a JSON representation of the current statistics.
28    pub fn to_json(&self) -> Result<String, serde_json::Error> {
29        serde_json::to_string_pretty(self)
30    }
31}
32
33#[cfg(test)]
34mod tests {
35    use super::*;
36
37    #[test]
38    fn test_stats_new_empty() {
39        let stats = Stats::new();
40        let json = stats.to_json().unwrap();
41        assert!(json.contains("\"total_requests\": 0"));
42    }
43
44    #[test]
45    fn test_stats_tracking_and_json() {
46        let mut stats = Stats::new();
47        stats.record(200);
48        stats.record(404);
49        stats.record(404);
50        stats.record(500);
51
52        let json = stats.to_json().unwrap();
53        assert!(json.contains("\"total_requests\": 4"));
54        assert!(json.contains("\"404\": 2"));
55        assert!(json.contains("\"500\": 1"));
56        assert!(json.contains("\"200\": 1"));
57    }
58}