use crate::{IntCounterWithLabels, Labels};
use prometheus::core::{Atomic, AtomicF64, AtomicI64, GenericCounter, GenericGauge, Number};
pub type IntGaugeGuard = GenericGaugeGuard<AtomicI64>;
pub type GaugeGuard = GenericGaugeGuard<AtomicF64>;
pub struct GenericGaugeGuard<P: Atomic + 'static> {
value: P::T,
gauge: &'static GenericGauge<P>,
}
impl<P: Atomic + 'static> Drop for GenericGaugeGuard<P> {
fn drop(&mut self) {
self.gauge.sub(self.value);
}
}
pub trait GuardedGauge<P: Atomic + 'static> {
#[must_use]
fn guarded_inc(&'static self) -> GenericGaugeGuard<P>;
#[must_use]
fn guarded_add(&'static self, v: P::T) -> GenericGaugeGuard<P>;
}
impl<P: Atomic + 'static> GuardedGauge<P> for GenericGauge<P> {
fn guarded_inc(&'static self) -> GenericGaugeGuard<P> {
self.inc();
GenericGaugeGuard {
value: <P::T as Number>::from_i64(1),
gauge: self,
}
}
fn guarded_add(&'static self, v: P::T) -> GenericGaugeGuard<P> {
self.add(v);
GenericGaugeGuard {
value: v,
gauge: self,
}
}
}
pub struct DeferredAddWithLabels<'a, L: Labels> {
value: u64,
metric: &'a IntCounterWithLabels<L>,
labels: L,
}
impl<'a, L: Labels> Drop for DeferredAddWithLabels<'a, L> {
fn drop(&mut self) {
self.metric.add(self.value, &self.labels)
}
}
impl<'a, L: Labels> DeferredAddWithLabels<'a, L> {
pub(crate) fn new(metric: &'a IntCounterWithLabels<L>, value: u64, labels: L) -> Self {
Self {
value,
metric,
labels,
}
}
pub fn with_labels(mut self, new_labels: L) -> DeferredAddWithLabels<'a, L> {
self.labels = new_labels;
self
}
pub fn complete_add(self) {
drop(self)
}
}
pub struct DeferredAdd<'a, P: Atomic> {
value: P::T,
metric: &'a GenericCounter<P>,
}
impl<'a, P: Atomic> DeferredAdd<'a, P> {
pub fn complete_add(self) {
drop(self)
}
}
impl<'a, P: Atomic> Drop for DeferredAdd<'a, P> {
fn drop(&mut self) {
self.metric.inc_by(self.value);
}
}
pub trait DeferredCounter<P: Atomic + 'static> {
#[must_use]
fn deferred_inc(&'static self) -> DeferredAdd<P> {
self.deferred_add(<P::T as Number>::from_i64(1))
}
#[must_use]
fn deferred_add(&'static self, v: P::T) -> DeferredAdd<P>;
}
impl<P: Atomic + 'static> DeferredCounter<P> for GenericCounter<P> {
fn deferred_add(&'static self, v: P::T) -> DeferredAdd<P> {
DeferredAdd {
value: v,
metric: self,
}
}
}