use std::hash::Hash;
use prometheus_client::{encoding::EncodeMetric, metrics::counter::Counter};
use crate::{
traits::{EncodeLabelSet, GaugeValue, HistogramValue},
wrappers::{Family, Gauge, Histogram, Info},
Buckets, Metrics,
};
#[derive(Debug, Clone, Copy)]
pub struct MetricBuilder<B = (), L = ()> {
buckets: B,
labels: L,
}
impl Default for MetricBuilder {
fn default() -> Self {
Self::new()
}
}
impl MetricBuilder {
pub const fn new() -> Self {
Self {
buckets: (),
labels: (),
}
}
}
impl<L> MetricBuilder<(), L> {
pub fn with_buckets(self, buckets: impl Into<Buckets>) -> MetricBuilder<Buckets, L> {
MetricBuilder {
buckets: buckets.into(),
labels: self.labels,
}
}
}
impl<B> MetricBuilder<B> {
pub fn with_labels<L>(self, labels: L) -> MetricBuilder<B, L> {
MetricBuilder {
buckets: self.buckets,
labels,
}
}
}
pub trait BuildMetric: 'static + Sized {
type Builder: Copy;
fn build(builder: Self::Builder) -> Self;
}
impl<N, A> BuildMetric for Counter<N, A>
where
Counter<N, A>: 'static + EncodeMetric + Default,
{
type Builder = MetricBuilder;
fn build(_builder: Self::Builder) -> Self {
Self::default()
}
}
impl<V: GaugeValue> BuildMetric for Gauge<V> {
type Builder = MetricBuilder;
fn build(_builder: Self::Builder) -> Self {
Self::default()
}
}
impl<V: HistogramValue> BuildMetric for Histogram<V> {
type Builder = MetricBuilder<Buckets>;
fn build(builder: Self::Builder) -> Self {
Histogram::new(builder.buckets)
}
}
impl<S: 'static + EncodeLabelSet> BuildMetric for Info<S> {
type Builder = MetricBuilder;
fn build(_builder: Self::Builder) -> Self {
Self::default()
}
}
impl<S, M, B, L> BuildMetric for Family<S, M, L>
where
S: 'static + Clone + Eq + Hash,
M: BuildMetric<Builder = MetricBuilder<B, ()>>,
B: Copy,
L: 'static + Copy,
Family<S, M, L>: EncodeMetric,
{
type Builder = MetricBuilder<B, L>;
fn build(builder: Self::Builder) -> Self {
let item_builder = MetricBuilder {
buckets: builder.buckets,
labels: (),
};
Family::new(item_builder, builder.labels)
}
}
impl<M: Metrics + Default> BuildMetric for M {
type Builder = ();
fn build((): Self::Builder) -> Self {
Self::default()
}
}