1use std::sync::Arc;
2
3use crate::IntoF64;
4
5pub trait CounterFn {
7 fn increment(&self, value: u64);
9
10 fn absolute(&self, value: u64);
21}
22
23pub trait GaugeFn {
25 fn increment(&self, value: f64);
27
28 fn decrement(&self, value: f64);
30
31 fn set(&self, value: f64);
33}
34
35pub trait HistogramFn {
37 fn record(&self, value: f64);
39}
40
41#[derive(Clone)]
43#[must_use = "counters do nothing unless you use them"]
44pub struct Counter {
45 inner: Option<Arc<dyn CounterFn + Send + Sync>>,
46}
47
48#[derive(Clone)]
50#[must_use = "gauges do nothing unless you use them"]
51pub struct Gauge {
52 inner: Option<Arc<dyn GaugeFn + Send + Sync>>,
53}
54
55#[derive(Clone)]
57#[must_use = "histograms do nothing unless you use them"]
58pub struct Histogram {
59 inner: Option<Arc<dyn HistogramFn + Send + Sync>>,
60}
61
62impl Counter {
63 pub fn noop() -> Self {
68 Self { inner: None }
69 }
70
71 pub fn from_arc<F: CounterFn + Send + Sync + 'static>(a: Arc<F>) -> Self {
73 Self { inner: Some(a) }
74 }
75
76 pub fn increment(&self, value: u64) {
78 if let Some(c) = &self.inner {
79 c.increment(value)
80 }
81 }
82
83 pub fn absolute(&self, value: u64) {
85 if let Some(c) = &self.inner {
86 c.absolute(value)
87 }
88 }
89}
90
91impl Gauge {
92 pub fn noop() -> Self {
97 Self { inner: None }
98 }
99
100 pub fn from_arc<F: GaugeFn + Send + Sync + 'static>(a: Arc<F>) -> Self {
102 Self { inner: Some(a) }
103 }
104
105 pub fn increment<T: IntoF64>(&self, value: T) {
107 if let Some(g) = &self.inner {
108 g.increment(value.into_f64())
109 }
110 }
111
112 pub fn decrement<T: IntoF64>(&self, value: T) {
114 if let Some(g) = &self.inner {
115 g.decrement(value.into_f64())
116 }
117 }
118
119 pub fn set<T: IntoF64>(&self, value: T) {
121 if let Some(g) = &self.inner {
122 g.set(value.into_f64())
123 }
124 }
125}
126
127impl Histogram {
128 pub fn noop() -> Self {
133 Self { inner: None }
134 }
135
136 pub fn from_arc<F: HistogramFn + Send + Sync + 'static>(a: Arc<F>) -> Self {
138 Self { inner: Some(a) }
139 }
140
141 pub fn record<T: IntoF64>(&self, value: T) {
143 if let Some(ref inner) = self.inner {
144 inner.record(value.into_f64())
145 }
146 }
147}
148
149impl<T> CounterFn for Arc<T>
150where
151 T: CounterFn,
152{
153 fn increment(&self, value: u64) {
154 (**self).increment(value)
155 }
156
157 fn absolute(&self, value: u64) {
158 (**self).absolute(value)
159 }
160}
161impl<T> GaugeFn for Arc<T>
162where
163 T: GaugeFn,
164{
165 fn increment(&self, value: f64) {
166 (**self).increment(value)
167 }
168
169 fn decrement(&self, value: f64) {
170 (**self).decrement(value)
171 }
172
173 fn set(&self, value: f64) {
174 (**self).set(value)
175 }
176}
177
178impl<T> HistogramFn for Arc<T>
179where
180 T: HistogramFn,
181{
182 fn record(&self, value: f64) {
183 (**self).record(value);
184 }
185}
186
187impl<T> From<Arc<T>> for Counter
188where
189 T: CounterFn + Send + Sync + 'static,
190{
191 fn from(inner: Arc<T>) -> Self {
192 Counter::from_arc(inner)
193 }
194}
195
196impl<T> From<Arc<T>> for Gauge
197where
198 T: GaugeFn + Send + Sync + 'static,
199{
200 fn from(inner: Arc<T>) -> Self {
201 Gauge::from_arc(inner)
202 }
203}
204
205impl<T> From<Arc<T>> for Histogram
206where
207 T: HistogramFn + Send + Sync + 'static,
208{
209 fn from(inner: Arc<T>) -> Self {
210 Histogram::from_arc(inner)
211 }
212}