use std::hash::Hasher;
use ahash::AHasher;
use crate::cow::Cow;
pub type SharedString = Cow<'static, str>;
#[derive(Debug, Default)]
pub struct KeyHasher(AHasher);
impl Hasher for KeyHasher {
fn finish(&self) -> u64 {
self.0.finish()
}
fn write(&mut self, bytes: &[u8]) {
self.0.write(bytes)
}
}
#[derive(Clone, Debug)]
pub enum GaugeValue {
Absolute(f64),
Increment(f64),
Decrement(f64),
}
impl GaugeValue {
pub fn update_value(&self, input: f64) -> f64 {
match self {
GaugeValue::Absolute(val) => *val,
GaugeValue::Increment(val) => input + val,
GaugeValue::Decrement(val) => input - val,
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Unit {
Count,
Percent,
Seconds,
Milliseconds,
Microseconds,
Nanoseconds,
Tebibytes,
Gibibytes,
Mebibytes,
Kibibytes,
Bytes,
TerabitsPerSecond,
GigabitsPerSecond,
MegabitsPerSecond,
KilobitsPerSecond,
BitsPerSecond,
CountPerSecond,
}
impl Unit {
pub fn as_str(&self) -> &'static str {
match self {
Unit::Count => "count",
Unit::Percent => "percent",
Unit::Seconds => "seconds",
Unit::Milliseconds => "milliseconds",
Unit::Microseconds => "microseconds",
Unit::Nanoseconds => "nanoseconds",
Unit::Tebibytes => "tebibytes",
Unit::Gibibytes => "gibibytes",
Unit::Mebibytes => "mebibytes",
Unit::Kibibytes => "kibibytes",
Unit::Bytes => "bytes",
Unit::TerabitsPerSecond => "terabits_per_second",
Unit::GigabitsPerSecond => "gigabits_per_second",
Unit::MegabitsPerSecond => "megabits_per_second",
Unit::KilobitsPerSecond => "kilobits_per_second",
Unit::BitsPerSecond => "bits_per_second",
Unit::CountPerSecond => "count_per_second",
}
}
pub fn as_canonical_label(&self) -> &'static str {
match self {
Unit::Count => "",
Unit::Percent => "%",
Unit::Seconds => "s",
Unit::Milliseconds => "ms",
Unit::Microseconds => "μs",
Unit::Nanoseconds => "ns",
Unit::Tebibytes => "TiB",
Unit::Gibibytes => "GiB",
Unit::Mebibytes => "MiB",
Unit::Kibibytes => "KiB",
Unit::Bytes => "B",
Unit::TerabitsPerSecond => "Tbps",
Unit::GigabitsPerSecond => "Gbps",
Unit::MegabitsPerSecond => "Mbps",
Unit::KilobitsPerSecond => "kbps",
Unit::BitsPerSecond => "bps",
Unit::CountPerSecond => "/s",
}
}
pub fn from_string(s: &str) -> Option<Unit> {
match s {
"count" => Some(Unit::Count),
"percent" => Some(Unit::Percent),
"seconds" => Some(Unit::Seconds),
"milliseconds" => Some(Unit::Milliseconds),
"microseconds" => Some(Unit::Microseconds),
"nanoseconds" => Some(Unit::Nanoseconds),
"tebibytes" => Some(Unit::Tebibytes),
"gibibytes" => Some(Unit::Gibibytes),
"mebibytes" => Some(Unit::Mebibytes),
"kibibytes" => Some(Unit::Kibibytes),
"bytes" => Some(Unit::Bytes),
"terabits_per_second" => Some(Unit::TerabitsPerSecond),
"gigabits_per_second" => Some(Unit::GigabitsPerSecond),
"megabits_per_second" => Some(Unit::MegabitsPerSecond),
"kilobits_per_second" => Some(Unit::KilobitsPerSecond),
"bits_per_second" => Some(Unit::BitsPerSecond),
"count_per_second" => Some(Unit::CountPerSecond),
_ => None,
}
}
pub fn is_time_based(&self) -> bool {
matches!(self, Unit::Seconds | Unit::Milliseconds | Unit::Microseconds | Unit::Nanoseconds)
}
pub fn is_data_based(&self) -> bool {
matches!(
self,
Unit::Tebibytes
| Unit::Gibibytes
| Unit::Mebibytes
| Unit::Kibibytes
| Unit::Bytes
| Unit::TerabitsPerSecond
| Unit::GigabitsPerSecond
| Unit::MegabitsPerSecond
| Unit::KilobitsPerSecond
| Unit::BitsPerSecond
)
}
pub fn is_data_rate_based(&self) -> bool {
matches!(
self,
Unit::TerabitsPerSecond
| Unit::GigabitsPerSecond
| Unit::MegabitsPerSecond
| Unit::KilobitsPerSecond
| Unit::BitsPerSecond
)
}
}
pub trait IntoF64 {
fn into_f64(self) -> f64;
}
impl IntoF64 for f64 {
fn into_f64(self) -> f64 {
self
}
}
impl IntoF64 for core::time::Duration {
fn into_f64(self) -> f64 {
self.as_secs_f64()
}
}
into_f64!(i8, u8, i16, u16, i32, u32, f32);
#[doc(hidden)]
pub fn __into_f64<V: IntoF64>(value: V) -> f64 {
value.into_f64()
}
macro_rules! into_f64 {
($($ty:ty),*) => {
$(
impl IntoF64 for $ty {
fn into_f64(self) -> f64 {
f64::from(self)
}
}
)*
};
}
use into_f64;
#[cfg(test)]
mod tests {
use std::time::Duration;
use super::{IntoF64, Unit};
#[test]
fn test_unit_conversions() {
let all_variants = vec![
Unit::Count,
Unit::Percent,
Unit::Seconds,
Unit::Milliseconds,
Unit::Microseconds,
Unit::Nanoseconds,
Unit::Tebibytes,
Unit::Gibibytes,
Unit::Mebibytes,
Unit::Kibibytes,
Unit::Bytes,
Unit::TerabitsPerSecond,
Unit::GigabitsPerSecond,
Unit::MegabitsPerSecond,
Unit::KilobitsPerSecond,
Unit::BitsPerSecond,
Unit::CountPerSecond,
];
for variant in all_variants {
let s = variant.as_str();
let parsed = Unit::from_string(s);
assert_eq!(Some(variant), parsed);
}
}
#[test]
fn into_f64() {
fn test<T: IntoF64>(val: T) {
assert!(!val.into_f64().is_nan());
}
test::<i8>(1);
test::<u8>(1);
test::<i16>(1);
test::<u16>(1);
test::<i32>(1);
test::<u32>(1);
test::<f32>(1.0);
test::<f64>(1.0);
test::<Duration>(Duration::from_secs(1));
}
}