use crate::Report;
use core::num::NonZeroU64;
pub trait ReportExt: Report {
fn batched(self, threshold: NonZeroU64) -> Batch<Self>
where
Self: Sized,
{
Batch {
report: self,
threshold,
pending: 0,
}
}
}
impl<T: Report + ?Sized> ReportExt for T {}
#[derive(Debug)]
#[must_use = "report through the batch; dropping it only flushes pending counts"]
pub struct Batch<R: Report> {
report: R,
threshold: NonZeroU64,
pending: u64,
}
impl<R: Report> Batch<R> {
#[track_caller]
pub fn advance(&mut self, completed: u64) {
if let Some(sum) = self.pending.checked_add(completed) {
self.pending = sum;
} else {
self.flush();
self.pending = completed;
}
if self.pending >= self.threshold.get() {
self.flush();
}
}
#[track_caller]
pub fn flush(&mut self) {
if self.pending != 0 {
self.report.advance(core::mem::take(&mut self.pending));
}
}
pub fn pending(&self) -> u64 {
self.pending
}
}
impl<R: Report> Drop for Batch<R> {
fn drop(&mut self) {
self.flush();
}
}