use std::time::Duration;
use crate::MetricMeta;
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum MetricType {
Counter,
Gauge,
Distribution,
Timer,
}
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
pub enum MetricUnit {
Unknown,
Seconds,
Bytes,
}
#[derive(Debug, Clone, Copy)]
pub struct MetricValue {
value: f64,
}
impl MetricValue {
pub fn new(value: f64) -> Self {
Self { value }
}
pub fn get(&self) -> f64 {
self.value
}
}
pub trait IntoMetricValue {
fn into_metric_value(self, meta: &MetricMeta) -> MetricValue;
}
macro_rules! into_metric_value {
($($ty:ident),+) => {
$(
impl IntoMetricValue for $ty {
#[inline(always)]
fn into_metric_value(self: $ty, _meta: &MetricMeta) -> MetricValue {
MetricValue::new(self as f64)
}
}
)+
};
}
#[rustfmt::skip]
into_metric_value!(
i8, i16, i32, i64, i128, isize,
u8, u16, u32, u64, u128, usize,
f32, f64
);
impl IntoMetricValue for bool {
fn into_metric_value(self, _meta: &MetricMeta) -> MetricValue {
MetricValue::new(if self { 1. } else { 0. })
}
}
impl IntoMetricValue for Duration {
fn into_metric_value(self, meta: &MetricMeta) -> MetricValue {
let secs = self.as_secs_f64();
MetricValue::new(match meta.unit() {
MetricUnit::Unknown if meta.ty() == MetricType::Timer => secs * 1_000.,
_ => secs,
})
}
}