use std::borrow::Cow;
use std::ops::Deref;
use std::pin::Pin;
use crate::WrapMetric;
use crate::{Format, Metric, MetricEntry};
pub struct MetricBuilder(metriken_core::dynmetrics::MetricBuilder);
impl MetricBuilder {
pub fn new(name: impl Into<Cow<'static, str>>) -> Self {
Self(metriken_core::dynmetrics::MetricBuilder::new(name.into()))
}
pub fn description(self, desc: impl Into<Cow<'static, str>>) -> Self {
Self(self.0.description(desc))
}
pub fn metadata(self, key: impl Into<String>, value: impl Into<String>) -> Self {
Self(self.0.metadata(key, value))
}
pub fn formatter(self, formatter: fn(&MetricEntry, Format) -> String) -> Self {
let translated: fn(&metriken_core::MetricEntry, Format) -> String =
unsafe { std::mem::transmute(formatter) };
Self(self.0.formatter(translated))
}
pub fn into_entry(self) -> MetricEntry {
MetricEntry(self.0.into_entry())
}
pub fn build<T: Metric>(self, metric: T) -> DynBoxedMetric<T> {
DynBoxedMetric::new(metric, self.into_entry())
}
}
pub struct DynPinnedMetric<M: Metric>(metriken_core::dynmetrics::DynPinnedMetric<WrapMetric<M>>);
impl<M: Metric> DynPinnedMetric<M> {
pub fn new(metric: M) -> Self {
Self(metriken_core::dynmetrics::DynPinnedMetric::new(
WrapMetric::new(metric),
))
}
pub fn register(self: Pin<&Self>, entry: MetricEntry) {
let this = unsafe { self.map_unchecked(|this| &this.0) };
this.register(entry.0);
}
}
impl<M: Metric> Deref for DynPinnedMetric<M> {
type Target = M;
#[inline]
fn deref(&self) -> &Self::Target {
&self.0
}
}
pub struct DynBoxedMetric<M: Metric> {
metric: Pin<Box<DynPinnedMetric<M>>>,
}
impl<M: Metric> DynBoxedMetric<M> {
pub fn new(metric: M, entry: MetricEntry) -> Self {
let this = Self::unregistered(metric);
this.register(entry);
this
}
fn unregistered(metric: M) -> Self {
Self {
metric: Box::pin(DynPinnedMetric::new(metric)),
}
}
fn register(&self, entry: MetricEntry) {
self.metric.as_ref().register(entry)
}
}
impl<M: Metric> Deref for DynBoxedMetric<M> {
type Target = M;
#[inline]
fn deref(&self) -> &Self::Target {
&self.metric
}
}