use std::marker::PhantomData;
use crate::{Format, Metric, MetricEntry, Request};
pub trait InjectedProvider: Send + Sync + 'static {
fn provide(request: &mut Request<'_>);
}
#[repr(transparent)]
pub struct MetricWrapper<M, P> {
metric: M,
provider: PhantomData<P>,
}
impl<M, P> MetricWrapper<M, P> {
pub const fn new(metric: M) -> Self {
Self {
metric,
provider: PhantomData,
}
}
pub const fn from_ref(metric: &M) -> &Self {
unsafe { &*(metric as *const M as *const Self) }
}
}
impl<M, P> Metric for MetricWrapper<M, P>
where
M: Metric,
P: InjectedProvider,
{
fn is_enabled(&self) -> bool {
self.metric.is_enabled()
}
fn as_any(&self) -> Option<&dyn std::any::Any> {
self.metric.as_any()
}
fn value(&self) -> Option<crate::Value<'_>> {
self.metric.value()
}
fn load_window(&self) -> Option<crate::Window> {
self.metric.load_window()
}
fn value_with_window(&self) -> (Option<crate::Value<'_>>, Option<crate::Window>) {
self.metric.value_with_window()
}
fn provide<'a>(&'a self, request: &mut Request<'a>) {
<P as InjectedProvider>::provide(request);
self.metric.provide(request)
}
}
pub struct FormattingFn(pub fn(&MetricEntry, Format) -> String);