pub(crate) use super::bundle::{DiagnosticBundle, ErrorContext};
use super::error_codes::NamErrorCode;
#[cfg(test)]
pub(crate) use super::format::days_to_date;
use super::format::timestamp;
use super::snapshot::RuntimeSnapshot;
#[cfg(test)]
pub(crate) use super::snapshot::{ACTIVE_MODEL_NAME, ACTIVE_SAMPLE_RATE};
use super::system_info::SystemSnapshot;
use std::fmt;
#[derive(Debug)]
pub struct NamDiagnostic {
code: NamErrorCode,
user_message: String,
user_hint: String,
params: Vec<(&'static str, String)>,
system: SystemSnapshot,
}
impl NamDiagnostic {
#[cold]
pub fn new(code: NamErrorCode, system: &SystemSnapshot) -> Self {
Self {
code,
user_message: String::new(),
user_hint: String::new(),
params: Vec::new(),
system: system.clone(),
}
}
pub fn message(mut self, msg: impl Into<String>) -> Self {
self.user_message = msg.into();
self
}
pub fn hint(mut self, hint: impl Into<String>) -> Self {
self.user_hint = hint.into();
self
}
pub fn param(mut self, key: &'static str, value: impl fmt::Display) -> Self {
self.params.push((key, value.to_string()));
self
}
pub fn timestamp() -> String {
timestamp()
}
pub(crate) fn support_block(&self) -> String {
DiagnosticBundle {
system: self.system.clone(),
runtime: RuntimeSnapshot::default(),
error: Some(ErrorContext {
code: self.code,
params: self.params.clone(),
}),
full: false,
}
.render()
}
pub fn emit(&self) {
log::error!(
"{}\n\n{}\n\n{}",
self.user_message,
if self.user_hint.is_empty() {
""
} else {
&self.user_hint
},
self.support_block()
);
}
pub fn emit_warning(&self) {
log::warn!(
"{}\n\n{}\n\n{}",
self.user_message,
if self.user_hint.is_empty() {
""
} else {
&self.user_hint
},
self.support_block()
);
}
pub fn error_code(&self) -> NamErrorCode {
self.code
}
}
impl fmt::Display for NamDiagnostic {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "[{}] {}", self.code.code(), self.user_message)
}
}
impl std::error::Error for NamDiagnostic {}
#[cfg(test)]
#[path = "diagnostic_test.rs"]
mod diagnostic_test;