use std::{fmt::Debug, time::{Duration, Instant}};
pub trait ErrorHelper<T: Debug> {
fn with_error<F: FnOnce(&T)>(self, f: F) -> Self;
fn take_error<F: FnOnce(T)>(self, f: F);
}
impl<R, E: Debug> ErrorHelper<E> for Result<R, E> {
fn with_error<F: FnOnce(&E)>(self, f: F) -> Self {
match self {
Ok(ok) => Ok(ok),
Err(error) => {
f(&error);
Err(error)
}
}
}
fn take_error<F: FnOnce(E)>(self, f: F) {
if let Err(error) = self {
f(error);
}
}
}
pub struct MaxErrorInterval {
last_report: Instant,
min_wait: Duration,
redundant_calls: usize,
}
impl MaxErrorInterval {
pub fn new(interval: Duration) -> Self {
MaxErrorInterval {
last_report: Instant::now() - interval * 2,
min_wait: interval,
redundant_calls: 0,
}
}
pub fn check(&mut self) -> bool {
let now = Instant::now();
if self.min_wait <= now - self.last_report {
self.last_report = now;
true
} else {
false
}
}
pub fn calls(&mut self) -> usize {
std::mem::replace(&mut self.redundant_calls, 0)
}
}