1use std::sync::{Arc, Mutex};
2
3#[derive(Debug, Clone, PartialEq, Eq)]
4pub struct UsageEvent {
5 pub action: String,
6 pub upstream: Option<String>,
7 pub success: bool,
8 pub bytes: usize,
9}
10
11pub trait UsageSink: Send + Sync {
12 fn record(&self, event: UsageEvent);
13}
14
15#[derive(Debug, Default)]
16pub struct NoopUsageSink;
17
18impl UsageSink for NoopUsageSink {
19 fn record(&self, _event: UsageEvent) {}
20}
21
22#[derive(Debug, Default)]
23pub struct MemoryUsageSink {
24 events: Mutex<Vec<UsageEvent>>,
25}
26
27impl MemoryUsageSink {
28 #[must_use]
29 pub fn shared() -> Arc<Self> {
30 Arc::new(Self::default())
31 }
32
33 #[must_use]
34 pub fn events(&self) -> Vec<UsageEvent> {
35 self.events.lock().expect("usage sink poisoned").clone()
36 }
37}
38
39impl UsageSink for MemoryUsageSink {
40 fn record(&self, event: UsageEvent) {
41 self.events.lock().expect("usage sink poisoned").push(event);
42 }
43}
44
45#[cfg(test)]
46#[path = "usage_tests.rs"]
47mod tests;