use crate::output_prefs::OutputPrefs;
use std::io::{self, Write};
use std::sync::Mutex;
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct StageNumber(u32);
impl StageNumber {
#[must_use]
pub const fn new_unchecked(value: u32) -> Self {
Self(value)
}
#[must_use]
pub const fn get(self) -> u32 {
self.0
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct LocalizationKey(&'static str);
impl LocalizationKey {
#[must_use]
pub const fn new(value: &'static str) -> Self {
Self(value)
}
#[must_use]
pub const fn as_str(self) -> &'static str {
self.0
}
}
impl From<&'static str> for LocalizationKey {
fn from(s: &'static str) -> Self {
Self::new(s)
}
}
#[path = "status_pipeline.rs"]
mod pipeline;
#[path = "status_timing.rs"]
mod timing;
pub use pipeline::{PipelineStage, report_pipeline_stage};
pub use timing::VerboseTimingReporter;
#[path = "status_indicatif.rs"]
mod indicatif;
pub use self::indicatif::IndicatifReporter;
use self::indicatif::{format_completion_line, stage_label, task_progress_update};
pub trait StatusReporter: Send + Sync {
fn report_stage(&self, current: StageNumber, total: StageNumber, description: &str);
fn report_task_progress(&self, _current: u32, _total: u32, _description: &str) {}
fn report_complete(&self, tool_key: LocalizationKey);
}
pub struct AccessibleReporter<W: Write + Send = io::Stderr> {
prefs: OutputPrefs,
writer: Mutex<W>,
}
impl AccessibleReporter {
#[must_use]
pub fn new(prefs: OutputPrefs) -> Self {
Self {
prefs,
writer: Mutex::new(io::stderr()),
}
}
}
impl<W: Write + Send> AccessibleReporter<W> {
#[must_use]
pub const fn with_writer(prefs: OutputPrefs, writer: W) -> Self {
Self {
prefs,
writer: Mutex::new(writer),
}
}
}
impl<W: Write + Send> StatusReporter for AccessibleReporter<W> {
fn report_stage(&self, current: StageNumber, total: StageNumber, description: &str) {
let prefix = self.prefs.info_prefix();
let message = stage_label(current, total, description);
let mut w = self
.writer
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
drop(writeln!(w, "{prefix} {message}"));
}
fn report_complete(&self, tool_key: LocalizationKey) {
let line = format_completion_line(self.prefs, tool_key);
let mut w = self
.writer
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
drop(writeln!(w, "{line}"));
}
fn report_task_progress(&self, current: u32, total: u32, description: &str) {
let message = task_progress_update(current, total, description);
let mut w = self
.writer
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
drop(writeln!(w, "{}{message}", self.prefs.task_indent()));
}
}
pub struct SilentReporter;
impl StatusReporter for SilentReporter {
fn report_stage(&self, _current: StageNumber, _total: StageNumber, _description: &str) {}
fn report_complete(&self, _tool_key: LocalizationKey) {}
}
#[cfg(test)]
#[path = "status_tests.rs"]
mod tests;
#[cfg(test)]
use self::indicatif::STAGE6_INDEX;
#[cfg(test)]
use self::pipeline::PIPELINE_STAGE_TOTAL;
#[cfg(test)]
use crate::localization::keys;