use std::{
cell::Cell,
thread,
time::{Duration, Instant},
};
#[derive(Debug)]
pub struct ReportFilter {
interval: Duration,
last_timestamp: &'static thread::LocalKey<Cell<Option<Instant>>>,
}
impl ReportFilter {
#[doc(hidden)] pub const fn new(
interval: Duration,
last_timestamp: &'static thread::LocalKey<Cell<Option<Instant>>>,
) -> Self {
Self {
interval,
last_timestamp,
}
}
pub fn should_report(&self) -> bool {
let timestamp = self.last_timestamp.get();
let now = Instant::now();
if timestamp.is_none_or(|ts| now - ts > self.interval) {
self.last_timestamp.set(Some(now));
true
} else {
false
}
}
}
#[macro_export]
macro_rules! report_filter {
($interval:expr) => {{
thread_local! {
static LAST_TIMESTAMP: ::std::cell::Cell<::std::option::Option<::std::time::Instant>> =
::std::cell::Cell::new(::std::option::Option::None);
}
$crate::filter::ReportFilter::new($interval, &LAST_TIMESTAMP)
}};
}
pub use report_filter;