1use std::{
5 borrow::Cow,
6 sync::{Mutex, MutexGuard},
7};
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
11pub struct TaskId(pub u64);
12
13#[derive(Debug, Clone, PartialEq, Eq)]
15pub enum ProgressEvent {
16 Start {
17 id: TaskId,
18 label: Cow<'static, str>,
19 total: Option<u64>,
20 },
21 Advance {
22 id: TaskId,
23 delta: u64,
24 },
25 Message {
26 id: TaskId,
27 msg: Cow<'static, str>,
28 },
29 Finish {
30 id: TaskId,
31 },
32}
33
34pub trait ProgressSink: Send + Sync {
36 fn event(&self, ev: ProgressEvent);
37}
38
39pub trait WarningSink: Send + Sync {
41 fn warn(&self, w: Warning);
42}
43
44#[derive(Debug, Clone, PartialEq, Eq)]
46pub struct Warning {
47 pub kind: Cow<'static, str>,
49 pub message: String,
50}
51
52#[derive(Debug, Default, Clone, Copy)]
54pub struct NoopProgress;
55
56impl ProgressSink for NoopProgress {
57 fn event(&self, _ev: ProgressEvent) {}
58}
59
60#[derive(Debug, Default, Clone, Copy)]
62pub struct NoopWarnings;
63
64impl WarningSink for NoopWarnings {
65 fn warn(&self, _w: Warning) {}
66}
67
68#[derive(Debug, Default)]
70pub struct CollectingWarnings {
71 warnings: Mutex<Vec<Warning>>,
72}
73
74impl CollectingWarnings {
75 pub fn warnings(&self) -> Vec<Warning> {
76 self.guard().clone()
77 }
78
79 pub fn drain(&self) -> Vec<Warning> {
80 self.guard().drain(..).collect()
81 }
82
83 fn guard(&self) -> MutexGuard<'_, Vec<Warning>> {
84 match self.warnings.lock() {
85 Ok(guard) => guard,
86 Err(poisoned) => poisoned.into_inner(),
87 }
88 }
89}
90
91impl WarningSink for CollectingWarnings {
92 fn warn(&self, w: Warning) {
93 self.guard().push(w);
94 }
95}