use crate::{Stop, StopReason};
use alloc::{boxed::Box, sync::Arc};
pub trait Report: Send + Sync {
#[track_caller]
fn advance(&self, completed: u64);
fn may_report(&self) -> bool {
true
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub struct NoReport;
impl Report for NoReport {
#[inline(always)]
fn advance(&self, _: u64) {}
#[inline(always)]
fn may_report(&self) -> bool {
false
}
}
macro_rules! forward_report {
($($wrapper:ty),*) => {$(
impl<T: Report + ?Sized> Report for $wrapper {
#[inline]
#[track_caller]
fn advance(&self, completed: u64) {
(**self).advance(completed);
}
#[inline]
fn may_report(&self) -> bool {
(**self).may_report()
}
}
)*};
}
forward_report!(&T, &mut T, Box<T>, Arc<T>);
impl<T: Report> Report for Option<T> {
#[inline]
#[track_caller]
fn advance(&self, completed: u64) {
if let Some(report) = self {
report.advance(completed);
}
}
#[inline]
fn may_report(&self) -> bool {
self.as_ref().is_some_and(Report::may_report)
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub struct ProgressWithStop<S, R> {
pub stop: S,
pub report: R,
}
impl<S, R> ProgressWithStop<S, R> {
pub const fn new(stop: S, report: R) -> Self {
Self { stop, report }
}
}
impl<S: Stop, R: Send + Sync> Stop for ProgressWithStop<S, R> {
#[inline]
#[track_caller]
fn check(&self) -> Result<(), StopReason> {
self.stop.check()
}
#[inline]
fn may_stop(&self) -> bool {
self.stop.may_stop()
}
}
impl<S: Send + Sync, R: Report> Report for ProgressWithStop<S, R> {
#[inline]
#[track_caller]
fn advance(&self, completed: u64) {
self.report.advance(completed);
}
#[inline]
fn may_report(&self) -> bool {
self.report.may_report()
}
}