use super::request_agent;
use mbx_cache_core::{AgentRequest, AgentResponse};
pub(crate) fn note(message: &str) {
crate::logging::note(message);
}
static STDERR_RESERVED: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false);
pub(crate) fn reserve_stderr_for_compiler() {
STDERR_RESERVED.store(true, std::sync::atomic::Ordering::Relaxed);
}
pub(crate) fn report_shim_warning(message: &str) {
report_shim_diagnostic(Severity::Warning, message);
}
pub(crate) fn report_shim_error(message: &str) {
report_shim_diagnostic(Severity::Error, message);
}
#[derive(Clone, Copy)]
enum Severity {
Warning,
Error,
}
fn report_shim_diagnostic(severity: Severity, message: &str) {
let message = diagnostic_message(message);
let (label, request) = match severity {
Severity::Warning => (
"warning",
AgentRequest::RecordWarning {
message: message.clone(),
},
),
Severity::Error => (
"error",
AgentRequest::RecordError {
message: message.clone(),
},
),
};
let response = request_agent(&[request])
.ok()
.and_then(|responses| responses.into_iter().next());
let delivered = matches!(
(severity, response),
(Severity::Warning, Some(AgentResponse::WarningRecorded))
| (Severity::Error, Some(AgentResponse::ErrorRecorded))
);
if !delivered
&& (matches!(severity, Severity::Error)
|| !STDERR_RESERVED.load(std::sync::atomic::Ordering::Relaxed))
{
note(&format!("mbx[{label}]: {message}"));
}
}
pub(super) fn diagnostic_message(message: &str) -> String {
let mut message = message.replace(['\n', '\r', '\0'], "; ");
if message.len() > 2048 {
let end = (0..=2048).rfind(|&index| message.is_char_boundary(index));
message.truncate(end.unwrap_or_default());
message.push_str("...");
}
message
}