1use std::time::Instant;
4
5use crate::{Observation, ObservedValue, PutsSnapshot, TimeUnit};
6
7pub use self::counter::Counter;
8pub use self::gauge::*;
9pub use self::histogram::Histogram;
10pub use self::instrument_adapter::*;
11pub use self::label_filter::*;
12pub use self::meter::Meter;
13pub use self::other_instruments::*;
14pub use self::panel::*;
15pub use self::polled::*;
16pub use self::switches::*;
17pub use crate::cockpit::Cockpit;
18
19mod counter;
20mod fundamentals;
21mod gauge;
22mod histogram;
23mod instrument_adapter;
24#[cfg(feature = "jemalloc-ctl")]
25pub mod jemalloc;
26mod label_filter;
27mod meter;
28pub mod other_instruments;
29mod panel;
30pub mod polled;
31pub mod switches;
32
33#[derive(Debug, Clone)]
34pub enum Update {
36 Observations(u64, Instant),
38 Observation(Instant),
40 ObservationWithValue(ObservedValue, Instant),
42}
43
44impl Update {
45 pub fn observed_value(&self) -> Option<&ObservedValue> {
46 match self {
47 Update::ObservationWithValue(ref v, _) => Some(v),
48 Update::Observation(_) | Update::Observations(_, _) => None,
49 }
50 }
51}
52
53pub struct LabelAndUpdate<T>(pub T, pub Update);
57
58impl<T> From<Observation<T>> for LabelAndUpdate<T> {
59 fn from(obs: Observation<T>) -> LabelAndUpdate<T> {
60 match obs {
61 Observation::Observed {
62 label,
63 count,
64 timestamp,
65 ..
66 } => LabelAndUpdate(label, Update::Observations(count, timestamp)),
67 Observation::ObservedOne {
68 label, timestamp, ..
69 } => LabelAndUpdate(label, Update::Observation(timestamp)),
70 Observation::ObservedOneValue {
71 label,
72 value,
73 timestamp,
74 ..
75 } => LabelAndUpdate(label, Update::ObservationWithValue(value, timestamp)),
76 }
77 }
78}
79
80pub struct BorrowedLabelAndUpdate<'a, T: 'a>(pub &'a T, pub Update);
84
85impl<'a, T> From<&'a Observation<T>> for BorrowedLabelAndUpdate<'a, T> {
86 fn from(obs: &'a Observation<T>) -> BorrowedLabelAndUpdate<'a, T> {
87 match obs {
88 Observation::Observed {
89 label,
90 count,
91 timestamp,
92 ..
93 } => BorrowedLabelAndUpdate(label, Update::Observations(*count, *timestamp)),
94 Observation::ObservedOne {
95 label, timestamp, ..
96 } => BorrowedLabelAndUpdate(label, Update::Observation(*timestamp)),
97 Observation::ObservedOneValue {
98 label,
99 value,
100 timestamp,
101 ..
102 } => BorrowedLabelAndUpdate(label, Update::ObservationWithValue(*value, *timestamp)),
103 }
104 }
105}
106
107pub trait Updates {
112 fn update(&mut self, with: &Update) -> usize;
120}
121
122pub trait Instrument: Updates + PutsSnapshot {}
124
125fn duration_to_display_value(time: u64, current_unit: TimeUnit, target_unit: TimeUnit) -> u64 {
126 use TimeUnit::*;
127 match (current_unit, target_unit) {
128 (Nanoseconds, Nanoseconds) => time,
129 (Nanoseconds, Microseconds) => time / 1_000,
130 (Nanoseconds, Milliseconds) => time / 1_000_000,
131 (Nanoseconds, Seconds) => time / 1_000_000_000,
132 (Microseconds, Nanoseconds) => time * 1_000,
133 (Microseconds, Microseconds) => time,
134 (Microseconds, Milliseconds) => time / 1_000,
135 (Microseconds, Seconds) => time / 1_000_000,
136 (Milliseconds, Nanoseconds) => time * 1_000_000,
137 (Milliseconds, Microseconds) => time * 1_000,
138 (Milliseconds, Milliseconds) => time,
139 (Milliseconds, Seconds) => time / 1_000,
140 (Seconds, Nanoseconds) => time * 1_000_000_000,
141 (Seconds, Microseconds) => time * 1_000_000,
142 (Seconds, Milliseconds) => time * 1_000,
143 (Seconds, Seconds) => time,
144 }
145}
146
147#[cfg(test)]
148mod test_time_conversion {
149 use super::duration_to_display_value;
150 use crate::TimeUnit;
151
152 #[test]
153 fn duration_to_display_value_from_nanos() {
154 let nanos = 1_234_567_890;
155 assert_eq!(
156 duration_to_display_value(nanos, TimeUnit::Nanoseconds, TimeUnit::Nanoseconds),
157 1_234_567_890,
158 "to nanos"
159 );
160 assert_eq!(
161 duration_to_display_value(nanos, TimeUnit::Nanoseconds, TimeUnit::Microseconds),
162 1_234_567,
163 "to micros"
164 );
165 assert_eq!(
166 duration_to_display_value(nanos, TimeUnit::Nanoseconds, TimeUnit::Milliseconds),
167 1_234,
168 "to millis"
169 );
170 assert_eq!(
171 duration_to_display_value(nanos, TimeUnit::Nanoseconds, TimeUnit::Seconds),
172 1,
173 "to seconds"
174 );
175 }
176
177 #[test]
178 fn duration_to_display_value_from_micros() {
179 let micros = 1_234_567;
180 assert_eq!(
181 duration_to_display_value(micros, TimeUnit::Microseconds, TimeUnit::Nanoseconds),
182 1_234_567_000,
183 "to nanos"
184 );
185 assert_eq!(
186 duration_to_display_value(micros, TimeUnit::Microseconds, TimeUnit::Microseconds),
187 1_234_567,
188 "to micros"
189 );
190 assert_eq!(
191 duration_to_display_value(micros, TimeUnit::Microseconds, TimeUnit::Milliseconds),
192 1_234,
193 "to millis"
194 );
195 assert_eq!(
196 duration_to_display_value(micros, TimeUnit::Microseconds, TimeUnit::Seconds),
197 1,
198 "to seconds"
199 );
200 }
201
202 #[test]
203 fn duration_to_display_value_from_millis() {
204 let millis = 1_234;
205 assert_eq!(
206 duration_to_display_value(millis, TimeUnit::Milliseconds, TimeUnit::Nanoseconds),
207 1_234_000_000,
208 "to nanos"
209 );
210 assert_eq!(
211 duration_to_display_value(millis, TimeUnit::Milliseconds, TimeUnit::Microseconds),
212 1_234_000,
213 "to micros"
214 );
215 assert_eq!(
216 duration_to_display_value(millis, TimeUnit::Milliseconds, TimeUnit::Milliseconds),
217 1_234,
218 "to millis"
219 );
220 assert_eq!(
221 duration_to_display_value(millis, TimeUnit::Milliseconds, TimeUnit::Seconds),
222 1,
223 "to seconds"
224 );
225 }
226
227 #[test]
228 fn duration_to_display_value_from_seconds() {
229 let seconds = 1;
230 assert_eq!(
231 duration_to_display_value(seconds, TimeUnit::Seconds, TimeUnit::Nanoseconds),
232 1_000_000_000,
233 "to nanos"
234 );
235 assert_eq!(
236 duration_to_display_value(seconds, TimeUnit::Seconds, TimeUnit::Microseconds),
237 1_000_000,
238 "to micros"
239 );
240 assert_eq!(
241 duration_to_display_value(seconds, TimeUnit::Seconds, TimeUnit::Milliseconds),
242 1_000,
243 "to millis"
244 );
245 assert_eq!(
246 duration_to_display_value(seconds, TimeUnit::Seconds, TimeUnit::Seconds),
247 1,
248 "to seconds"
249 );
250 }
251}