use anyhow::{Result, bail};
use std::ops::{Add, AddAssign};
#[derive(Debug, Default)]
pub(crate) struct Metric<T> {
pending: T,
total: T,
}
impl<T: Copy + Add + AddAssign + Default> Metric<T> {
pub fn add(&mut self, n: T) {
self.pending += n;
}
pub fn flush(&mut self) -> T {
self.total += self.pending;
let delta = self.pending;
self.pending = T::default();
delta
}
}
impl<T: Copy + Add> Metric<T> {
pub fn total(&self) -> Result<T>
where
<T as std::ops::Add>::Output: std::cmp::PartialEq<T>,
{
if self.total + self.pending != self.total {
bail!("unflushed metrics");
}
Ok(self.total)
}
}
impl Metric<u64> {
pub fn increment(&mut self) {
self.pending += 1;
}
}