1use crate::{Stop, StopReason};
4use alloc::{boxed::Box, sync::Arc};
5
6pub trait Report: Send + Sync {
13 #[track_caller]
15 fn advance(&self, completed: u64);
16
17 fn may_report(&self) -> bool {
22 true
23 }
24}
25
26#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
28pub struct NoReport;
29
30impl Report for NoReport {
31 #[inline(always)]
32 fn advance(&self, _: u64) {}
33 #[inline(always)]
34 fn may_report(&self) -> bool {
35 false
36 }
37}
38
39macro_rules! forward_report {
41 ($($wrapper:ty),*) => {$(
42 impl<T: Report + ?Sized> Report for $wrapper {
43 #[inline]
44 #[track_caller]
45 fn advance(&self, completed: u64) {
46 (**self).advance(completed);
47 }
48 #[inline]
49 fn may_report(&self) -> bool {
50 (**self).may_report()
51 }
52 }
53 )*};
54}
55forward_report!(&T, &mut T, Box<T>, Arc<T>);
56
57impl<T: Report> Report for Option<T> {
59 #[inline]
60 #[track_caller]
61 fn advance(&self, completed: u64) {
62 if let Some(report) = self {
63 report.advance(completed);
64 }
65 }
66 #[inline]
67 fn may_report(&self) -> bool {
68 self.as_ref().is_some_and(Report::may_report)
69 }
70}
71
72#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
79pub struct ProgressWithStop<S, R> {
80 pub stop: S,
82 pub report: R,
84}
85
86impl<S, R> ProgressWithStop<S, R> {
87 pub const fn new(stop: S, report: R) -> Self {
89 Self { stop, report }
90 }
91}
92
93impl<S: Stop, R: Send + Sync> Stop for ProgressWithStop<S, R> {
94 #[inline]
95 #[track_caller]
96 fn check(&self) -> Result<(), StopReason> {
97 self.stop.check()
98 }
99 #[inline]
100 fn may_stop(&self) -> bool {
101 self.stop.may_stop()
102 }
103}
104
105impl<S: Send + Sync, R: Report> Report for ProgressWithStop<S, R> {
106 #[inline]
107 #[track_caller]
108 fn advance(&self, completed: u64) {
109 self.report.advance(completed);
110 }
111 #[inline]
112 fn may_report(&self) -> bool {
113 self.report.may_report()
114 }
115}