use std::{
borrow::Cow,
sync::{Mutex, MutexGuard},
};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct TaskId(pub u64);
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ProgressEvent {
Start {
id: TaskId,
label: Cow<'static, str>,
total: Option<u64>,
},
Advance {
id: TaskId,
delta: u64,
},
Message {
id: TaskId,
msg: Cow<'static, str>,
},
Finish {
id: TaskId,
},
}
pub trait ProgressSink: Send + Sync {
fn event(&self, ev: ProgressEvent);
}
pub trait WarningSink: Send + Sync {
fn warn(&self, w: Warning);
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Warning {
pub kind: Cow<'static, str>,
pub message: String,
}
#[derive(Debug, Default, Clone, Copy)]
pub struct NoopProgress;
impl ProgressSink for NoopProgress {
fn event(&self, _ev: ProgressEvent) {}
}
#[derive(Debug, Default, Clone, Copy)]
pub struct NoopWarnings;
impl WarningSink for NoopWarnings {
fn warn(&self, _w: Warning) {}
}
#[derive(Debug, Default)]
pub struct CollectingWarnings {
warnings: Mutex<Vec<Warning>>,
}
impl CollectingWarnings {
pub fn warnings(&self) -> Vec<Warning> {
self.guard().clone()
}
pub fn drain(&self) -> Vec<Warning> {
self.guard().drain(..).collect()
}
fn guard(&self) -> MutexGuard<'_, Vec<Warning>> {
match self.warnings.lock() {
Ok(guard) => guard,
Err(poisoned) => poisoned.into_inner(),
}
}
}
impl WarningSink for CollectingWarnings {
fn warn(&self, w: Warning) {
self.guard().push(w);
}
}