use std::{
io::Write,
sync::{
Arc,
Mutex,
},
};
use qubit_function::ArcConsumer;
use super::human_readable_progress_reporter::HumanReadableProgressReporter;
use crate::{
model::ProgressEvent,
reporter::ProgressReporter,
};
pub struct WriterProgressReporter<W> {
writer: Arc<Mutex<W>>,
inner: HumanReadableProgressReporter,
}
impl<W> WriterProgressReporter<W> {
#[inline]
pub const fn writer(&self) -> &Arc<Mutex<W>> {
&self.writer
}
}
impl<W> WriterProgressReporter<W>
where
W: Write + Send + 'static,
{
pub fn new(writer: Arc<Mutex<W>>) -> Self {
let consumer_writer = Arc::clone(&writer);
let consumer = ArcConsumer::new(move |line: &String| {
let mut writer = consumer_writer
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
writeln!(writer, "{line}").expect("progress reporter should write event");
});
Self {
writer,
inner: HumanReadableProgressReporter::new(consumer),
}
}
#[inline]
pub fn from_writer(writer: W) -> Self {
Self::new(Arc::new(Mutex::new(writer)))
}
}
impl<W> ProgressReporter for WriterProgressReporter<W>
where
W: Write + Send + 'static,
{
#[inline]
fn report(&self, event: &ProgressEvent) {
self.inner.report(event);
}
}