1use std::{fmt::Debug, 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 fn record_many(&self, value: f64, count: usize) {
42 for _ in 0..count {
43 self.record(value);
44 }
45 }
46}
47
48#[derive(Clone)]
50#[must_use = "counters do nothing unless you use them"]
51pub struct Counter {
52 inner: Option<Arc<dyn CounterFn + Send + Sync>>,
53}
54
55impl Debug for Counter {
56 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57 f.debug_struct("Counter").finish_non_exhaustive()
58 }
59}
60
61#[derive(Clone)]
63#[must_use = "gauges do nothing unless you use them"]
64pub struct Gauge {
65 inner: Option<Arc<dyn GaugeFn + Send + Sync>>,
66}
67
68impl Debug for Gauge {
69 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
70 f.debug_struct("Gauge").finish_non_exhaustive()
71 }
72}
73
74#[derive(Clone)]
76#[must_use = "histograms do nothing unless you use them"]
77pub struct Histogram {
78 inner: Option<Arc<dyn HistogramFn + Send + Sync>>,
79}
80
81impl Debug for Histogram {
82 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
83 f.debug_struct("Histogram").finish_non_exhaustive()
84 }
85}
86
87impl Counter {
88 pub fn noop() -> Self {
93 Self { inner: None }
94 }
95
96 pub fn from_arc<F: CounterFn + Send + Sync + 'static>(a: Arc<F>) -> Self {
98 Self { inner: Some(a) }
99 }
100
101 pub fn increment(&self, value: u64) {
103 if let Some(c) = &self.inner {
104 c.increment(value)
105 }
106 }
107
108 pub fn absolute(&self, value: u64) {
110 if let Some(c) = &self.inner {
111 c.absolute(value)
112 }
113 }
114}
115
116impl Gauge {
117 pub fn noop() -> Self {
122 Self { inner: None }
123 }
124
125 pub fn from_arc<F: GaugeFn + Send + Sync + 'static>(a: Arc<F>) -> Self {
127 Self { inner: Some(a) }
128 }
129
130 pub fn increment<T: IntoF64>(&self, value: T) {
132 if let Some(g) = &self.inner {
133 g.increment(value.into_f64())
134 }
135 }
136
137 pub fn decrement<T: IntoF64>(&self, value: T) {
139 if let Some(g) = &self.inner {
140 g.decrement(value.into_f64())
141 }
142 }
143
144 pub fn set<T: IntoF64>(&self, value: T) {
146 if let Some(g) = &self.inner {
147 g.set(value.into_f64())
148 }
149 }
150}
151
152impl Histogram {
153 pub fn noop() -> Self {
158 Self { inner: None }
159 }
160
161 pub fn from_arc<F: HistogramFn + Send + Sync + 'static>(a: Arc<F>) -> Self {
163 Self { inner: Some(a) }
164 }
165
166 pub fn record<T: IntoF64>(&self, value: T) {
168 if let Some(ref inner) = self.inner {
169 inner.record(value.into_f64())
170 }
171 }
172
173 pub fn record_many<T: IntoF64>(&self, value: T, count: usize) {
175 if let Some(ref inner) = self.inner {
176 inner.record_many(value.into_f64(), count)
177 }
178 }
179}
180
181impl<T> CounterFn for Arc<T>
182where
183 T: CounterFn,
184{
185 fn increment(&self, value: u64) {
186 (**self).increment(value)
187 }
188
189 fn absolute(&self, value: u64) {
190 (**self).absolute(value)
191 }
192}
193impl<T> GaugeFn for Arc<T>
194where
195 T: GaugeFn,
196{
197 fn increment(&self, value: f64) {
198 (**self).increment(value)
199 }
200
201 fn decrement(&self, value: f64) {
202 (**self).decrement(value)
203 }
204
205 fn set(&self, value: f64) {
206 (**self).set(value)
207 }
208}
209
210impl<T> HistogramFn for Arc<T>
211where
212 T: HistogramFn,
213{
214 fn record(&self, value: f64) {
215 (**self).record(value);
216 }
217}
218
219impl<T> From<Arc<T>> for Counter
220where
221 T: CounterFn + Send + Sync + 'static,
222{
223 fn from(inner: Arc<T>) -> Self {
224 Counter::from_arc(inner)
225 }
226}
227
228impl<T> From<Arc<T>> for Gauge
229where
230 T: GaugeFn + Send + Sync + 'static,
231{
232 fn from(inner: Arc<T>) -> Self {
233 Gauge::from_arc(inner)
234 }
235}
236
237impl<T> From<Arc<T>> for Histogram
238where
239 T: HistogramFn + Send + Sync + 'static,
240{
241 fn from(inner: Arc<T>) -> Self {
242 Histogram::from_arc(inner)
243 }
244}