mirror of https://github.com/zkat/miette.git
96 lines
3.0 KiB
Rust
96 lines
3.0 KiB
Rust
/*!
|
|
Reporters included with `miette`.
|
|
*/
|
|
use std::fmt;
|
|
|
|
use atty::Stream;
|
|
use once_cell::sync::OnceCell;
|
|
|
|
use crate::protocol::{Diagnostic, DiagnosticReportPrinter, Severity};
|
|
use crate::MietteError;
|
|
|
|
// NOTE(zkat): I don't understand why these three are "unreachable" when
|
|
// they're clearly being exported? Maybe a bug?
|
|
#[allow(unreachable_pub)]
|
|
pub use graphical_printer::*;
|
|
#[allow(unreachable_pub)]
|
|
pub use narratable_printer::*;
|
|
#[allow(unreachable_pub)]
|
|
pub use theme::*;
|
|
|
|
mod graphical_printer;
|
|
mod narratable_printer;
|
|
mod theme;
|
|
|
|
static REPORTER: OnceCell<Box<dyn DiagnosticReportPrinter + Send + Sync + 'static>> =
|
|
OnceCell::new();
|
|
|
|
/// Set the global [DiagnosticReportPrinter] that will be used when you report
|
|
/// using [crate::DiagnosticReport].
|
|
pub fn set_printer(
|
|
reporter: impl DiagnosticReportPrinter + Send + Sync + 'static,
|
|
) -> Result<(), MietteError> {
|
|
REPORTER
|
|
.set(Box::new(reporter))
|
|
.map_err(|_| MietteError::SetPrinterFailure)
|
|
}
|
|
|
|
/// Used by [crate::DiagnosticReport] to fetch the reporter that will be used to
|
|
/// print stuff out.
|
|
pub(crate) fn get_printer() -> &'static (dyn DiagnosticReportPrinter + Send + Sync + 'static) {
|
|
&**REPORTER.get_or_init(get_default_printer)
|
|
}
|
|
|
|
fn get_default_printer() -> Box<dyn DiagnosticReportPrinter + Send + Sync + 'static> {
|
|
let fancy = if let Ok(string) = std::env::var("NO_COLOR") {
|
|
string == "0"
|
|
} else if let Ok(string) = std::env::var("CLICOLOR") {
|
|
string != "0" || string == "1"
|
|
} else {
|
|
atty::is(Stream::Stdout) && atty::is(Stream::Stderr) && !ci_info::is_ci()
|
|
};
|
|
if fancy {
|
|
Box::new(GraphicalReportPrinter::new())
|
|
} else {
|
|
Box::new(NarratableReportPrinter)
|
|
}
|
|
}
|
|
|
|
/// Literally what it says on the tin.
|
|
#[derive(Debug, Clone)]
|
|
pub struct JokePrinter;
|
|
|
|
impl DiagnosticReportPrinter for JokePrinter {
|
|
fn debug(&self, diagnostic: &(dyn Diagnostic), f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
if f.alternate() {
|
|
return fmt::Debug::fmt(diagnostic, f);
|
|
}
|
|
|
|
let sev = match diagnostic.severity() {
|
|
Some(Severity::Error) | None => "error",
|
|
Some(Severity::Warning) => "warning",
|
|
Some(Severity::Advice) => "advice",
|
|
};
|
|
writeln!(
|
|
f,
|
|
"me, with {} {}: {}",
|
|
sev,
|
|
diagnostic,
|
|
diagnostic
|
|
.help()
|
|
.unwrap_or_else(|| Box::new(&"have you tried not failing?"))
|
|
)?;
|
|
writeln!(
|
|
f,
|
|
"miette, her eyes enormous: you {} miette? you {}? oh! oh! jail for mother! jail for mother for One Thousand Years!!!!",
|
|
diagnostic.code(),
|
|
diagnostic.snippets().map(|snippets| {
|
|
snippets.map(|snippet| snippet.message.map(|x| x.to_owned()))
|
|
.collect::<Option<Vec<String>>>()
|
|
}).flatten().map(|x| x.join(", ")).unwrap_or_else(||"try and cause miette to panic".into())
|
|
)?;
|
|
|
|
Ok(())
|
|
}
|
|
}
|