rustack_ses_core/
statistics.rs1use std::sync::atomic::{AtomicU64, Ordering};
7
8#[derive(Debug)]
10pub struct SendStatistics {
11 send_count: AtomicU64,
13 bounce_count: AtomicU64,
15 complaint_count: AtomicU64,
17 delivery_attempts: AtomicU64,
19 reject_count: AtomicU64,
21}
22
23impl Default for SendStatistics {
24 fn default() -> Self {
25 Self::new()
26 }
27}
28
29impl SendStatistics {
30 #[must_use]
32 pub fn new() -> Self {
33 Self {
34 send_count: AtomicU64::new(0),
35 bounce_count: AtomicU64::new(0),
36 complaint_count: AtomicU64::new(0),
37 delivery_attempts: AtomicU64::new(0),
38 reject_count: AtomicU64::new(0),
39 }
40 }
41
42 pub fn record_send(&self) {
44 self.send_count.fetch_add(1, Ordering::Relaxed);
45 self.delivery_attempts.fetch_add(1, Ordering::Relaxed);
46 }
47
48 #[must_use]
50 pub fn get_stats(&self) -> SendStats {
51 SendStats {
52 send_count: self.send_count.load(Ordering::Relaxed),
53 bounce_count: self.bounce_count.load(Ordering::Relaxed),
54 complaint_count: self.complaint_count.load(Ordering::Relaxed),
55 delivery_attempts: self.delivery_attempts.load(Ordering::Relaxed),
56 reject_count: self.reject_count.load(Ordering::Relaxed),
57 }
58 }
59}
60
61#[derive(Debug, Clone)]
63pub struct SendStats {
64 pub send_count: u64,
66 pub bounce_count: u64,
68 pub complaint_count: u64,
70 pub delivery_attempts: u64,
72 pub reject_count: u64,
74}
75
76#[derive(Debug, Clone)]
78pub struct SendQuotaConfig {
79 pub max_24_hour_send: f64,
81 pub max_send_rate: f64,
83}
84
85impl Default for SendQuotaConfig {
86 fn default() -> Self {
87 Self {
88 max_24_hour_send: 200.0,
89 max_send_rate: 1.0,
90 }
91 }
92}
93
94#[cfg(test)]
95mod tests {
96 use super::*;
97
98 #[test]
99 fn test_should_start_with_zero_counts() {
100 let stats = SendStatistics::new();
101 let snapshot = stats.get_stats();
102 assert_eq!(snapshot.send_count, 0);
103 assert_eq!(snapshot.bounce_count, 0);
104 assert_eq!(snapshot.complaint_count, 0);
105 assert_eq!(snapshot.delivery_attempts, 0);
106 assert_eq!(snapshot.reject_count, 0);
107 }
108
109 #[test]
110 fn test_should_increment_on_send() {
111 let stats = SendStatistics::new();
112 stats.record_send();
113 stats.record_send();
114 let snapshot = stats.get_stats();
115 assert_eq!(snapshot.send_count, 2);
116 assert_eq!(snapshot.delivery_attempts, 2);
117 assert_eq!(snapshot.bounce_count, 0);
118 }
119
120 #[test]
121 fn test_should_create_default_quota() {
122 let quota = SendQuotaConfig::default();
123 assert!((quota.max_24_hour_send - 200.0).abs() < f64::EPSILON);
124 assert!((quota.max_send_rate - 1.0).abs() < f64::EPSILON);
125 }
126}