1use std::hash::Hasher;
2
3use ahash::AHasher;
4
5use crate::cow::Cow;
6
7pub type SharedString = Cow<'static, str>;
19
20#[derive(Default)]
27pub struct KeyHasher(AHasher);
28
29impl Hasher for KeyHasher {
30 fn finish(&self) -> u64 {
31 self.0.finish()
32 }
33
34 fn write(&mut self, bytes: &[u8]) {
35 self.0.write(bytes)
36 }
37}
38
39#[derive(Clone, Debug)]
41pub enum GaugeValue {
42 Absolute(f64),
44 Increment(f64),
46 Decrement(f64),
48}
49
50impl GaugeValue {
51 pub fn update_value(&self, input: f64) -> f64 {
53 match self {
54 GaugeValue::Absolute(val) => *val,
55 GaugeValue::Increment(val) => input + val,
56 GaugeValue::Decrement(val) => input - val,
57 }
58 }
59}
60
61#[derive(Clone, Copy, Debug, Eq, PartialEq)]
66pub enum Unit {
67 Count,
69 Percent,
71 Seconds,
75 Milliseconds,
79 Microseconds,
83 Nanoseconds,
85 Tebibytes,
89 Gigibytes,
93 Mebibytes,
97 Kibibytes,
101 Bytes,
103 TerabitsPerSecond,
107 GigabitsPerSecond,
111 MegabitsPerSecond,
115 KilobitsPerSecond,
119 BitsPerSecond,
121 CountPerSecond,
123}
124
125impl Unit {
126 pub fn as_str(&self) -> &'static str {
128 match self {
129 Unit::Count => "count",
130 Unit::Percent => "percent",
131 Unit::Seconds => "seconds",
132 Unit::Milliseconds => "milliseconds",
133 Unit::Microseconds => "microseconds",
134 Unit::Nanoseconds => "nanoseconds",
135 Unit::Tebibytes => "tebibytes",
136 Unit::Gigibytes => "gigibytes",
137 Unit::Mebibytes => "mebibytes",
138 Unit::Kibibytes => "kibibytes",
139 Unit::Bytes => "bytes",
140 Unit::TerabitsPerSecond => "terabits_per_second",
141 Unit::GigabitsPerSecond => "gigabits_per_second",
142 Unit::MegabitsPerSecond => "megabits_per_second",
143 Unit::KilobitsPerSecond => "kilobits_per_second",
144 Unit::BitsPerSecond => "bits_per_second",
145 Unit::CountPerSecond => "count_per_second",
146 }
147 }
148
149 pub fn as_canonical_label(&self) -> &'static str {
156 match self {
157 Unit::Count => "",
158 Unit::Percent => "%",
159 Unit::Seconds => "s",
160 Unit::Milliseconds => "ms",
161 Unit::Microseconds => "μs",
162 Unit::Nanoseconds => "ns",
163 Unit::Tebibytes => "TiB",
164 Unit::Gigibytes => "GiB",
165 Unit::Mebibytes => "MiB",
166 Unit::Kibibytes => "KiB",
167 Unit::Bytes => "B",
168 Unit::TerabitsPerSecond => "Tbps",
169 Unit::GigabitsPerSecond => "Gbps",
170 Unit::MegabitsPerSecond => "Mbps",
171 Unit::KilobitsPerSecond => "kbps",
172 Unit::BitsPerSecond => "bps",
173 Unit::CountPerSecond => "/s",
174 }
175 }
176
177 pub fn from_string(s: &str) -> Option<Unit> {
181 match s {
182 "count" => Some(Unit::Count),
183 "percent" => Some(Unit::Percent),
184 "seconds" => Some(Unit::Seconds),
185 "milliseconds" => Some(Unit::Milliseconds),
186 "microseconds" => Some(Unit::Microseconds),
187 "nanoseconds" => Some(Unit::Nanoseconds),
188 "tebibytes" => Some(Unit::Tebibytes),
189 "gigibytes" => Some(Unit::Gigibytes),
190 "mebibytes" => Some(Unit::Mebibytes),
191 "kibibytes" => Some(Unit::Kibibytes),
192 "bytes" => Some(Unit::Bytes),
193 "terabits_per_second" => Some(Unit::TerabitsPerSecond),
194 "gigabits_per_second" => Some(Unit::GigabitsPerSecond),
195 "megabits_per_second" => Some(Unit::MegabitsPerSecond),
196 "kilobits_per_second" => Some(Unit::KilobitsPerSecond),
197 "bits_per_second" => Some(Unit::BitsPerSecond),
198 "count_per_second" => Some(Unit::CountPerSecond),
199 _ => None,
200 }
201 }
202
203 pub fn is_time_based(&self) -> bool {
205 matches!(self, Unit::Seconds | Unit::Milliseconds | Unit::Microseconds | Unit::Nanoseconds)
206 }
207
208 pub fn is_data_based(&self) -> bool {
210 matches!(
211 self,
212 Unit::Tebibytes
213 | Unit::Gigibytes
214 | Unit::Mebibytes
215 | Unit::Kibibytes
216 | Unit::Bytes
217 | Unit::TerabitsPerSecond
218 | Unit::GigabitsPerSecond
219 | Unit::MegabitsPerSecond
220 | Unit::KilobitsPerSecond
221 | Unit::BitsPerSecond
222 )
223 }
224
225 pub fn is_data_rate_based(&self) -> bool {
227 matches!(
228 self,
229 Unit::TerabitsPerSecond
230 | Unit::GigabitsPerSecond
231 | Unit::MegabitsPerSecond
232 | Unit::KilobitsPerSecond
233 | Unit::BitsPerSecond
234 )
235 }
236}
237
238pub trait IntoF64 {
243 fn into_f64(self) -> f64;
245}
246
247impl IntoF64 for f64 {
248 fn into_f64(self) -> f64 {
249 self
250 }
251}
252
253impl IntoF64 for core::time::Duration {
254 fn into_f64(self) -> f64 {
255 self.as_secs_f64()
256 }
257}
258
259into_f64!(i8, u8, i16, u16, i32, u32, f32);
260
261#[doc(hidden)]
263pub fn __into_f64<V: IntoF64>(value: V) -> f64 {
264 value.into_f64()
265}
266
267macro_rules! into_f64 {
268 ($($ty:ty),*) => {
269 $(
270 impl IntoF64 for $ty {
271 fn into_f64(self) -> f64 {
272 f64::from(self)
273 }
274 }
275 )*
276 };
277}
278
279pub(self) use into_f64;
280
281#[cfg(test)]
282mod tests {
283 use std::time::Duration;
284
285 use super::{IntoF64, Unit};
286
287 #[test]
288 fn test_unit_conversions() {
289 let all_variants = vec![
290 Unit::Count,
291 Unit::Percent,
292 Unit::Seconds,
293 Unit::Milliseconds,
294 Unit::Microseconds,
295 Unit::Nanoseconds,
296 Unit::Tebibytes,
297 Unit::Gigibytes,
298 Unit::Mebibytes,
299 Unit::Kibibytes,
300 Unit::Bytes,
301 Unit::TerabitsPerSecond,
302 Unit::GigabitsPerSecond,
303 Unit::MegabitsPerSecond,
304 Unit::KilobitsPerSecond,
305 Unit::BitsPerSecond,
306 Unit::CountPerSecond,
307 ];
308
309 for variant in all_variants {
310 let s = variant.as_str();
311 let parsed = Unit::from_string(s);
312 assert_eq!(Some(variant), parsed);
313 }
314 }
315
316 #[test]
317 fn into_f64() {
318 fn test<T: IntoF64>(val: T) {
319 assert!(!val.into_f64().is_nan());
320 }
321
322 test::<i8>(1);
323 test::<u8>(1);
324 test::<i16>(1);
325 test::<u16>(1);
326 test::<i32>(1);
327 test::<u32>(1);
328 test::<f32>(1.0);
329 test::<f64>(1.0);
330 test::<Duration>(Duration::from_secs(1));
331 }
332}