use std::{
any::Any,
fmt,
panic::{RefUnwindSafe, UnwindSafe},
process::ExitStatus,
sync::Arc,
};
pub trait BuildMessageLogger: Send + Sync + 'static {
fn log(&self, kind: BuildMessageKind, msg: BuildMessage<'_>, extra: &dyn Any);
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum BuildMessageKind {
GeneralWarning,
StderrForwarding,
#[non_exhaustive]
CommandFailed {
is_detection_cmd: bool,
exit_status: ExitStatus,
},
}
#[derive(Clone, Copy, Debug)]
#[non_exhaustive]
pub enum BuildMessage<'a> {
Str(&'a str),
}
impl fmt::Display for BuildMessage<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Str(s) => f.write_str(s),
}
}
}
#[derive(Clone)]
pub(crate) struct Logger(pub(crate) Arc<dyn BuildMessageLogger>);
impl UnwindSafe for Logger {}
impl RefUnwindSafe for Logger {}
impl Logger {
pub(crate) fn log(&self, kind: BuildMessageKind, msg: &str, extra: &dyn Any) {
self.0.log(kind, BuildMessage::Str(msg), extra);
}
}
impl fmt::Debug for Logger {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Logger").finish_non_exhaustive()
}
}