use serde::Serialize;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
#[cfg_attr(feature = "tsify", derive(tsify::Tsify))]
#[serde(rename_all = "camelCase")]
pub enum Severity {
Error,
Warning,
Note,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
#[cfg_attr(feature = "tsify", derive(tsify::Tsify))]
#[serde(rename_all = "camelCase")]
pub enum DiagnosticSource {
Source,
Internal,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
#[cfg_attr(feature = "tsify", derive(tsify::Tsify))]
#[serde(rename_all = "camelCase")]
pub struct Span {
pub start: u32,
pub end: u32,
}
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "tsify", derive(tsify::Tsify))]
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
pub struct Diagnostic {
pub severity: Severity,
pub source: DiagnosticSource,
pub code: &'static str,
pub message: String,
pub span: Span,
}
impl Diagnostic {
#[must_use]
pub(crate) fn source_too_large(bytes: usize) -> Self {
Self {
severity: Severity::Error,
source: DiagnosticSource::Source,
code: "aozora-md::source_too_large",
message: format!(
"source is {bytes} bytes, over the {} byte (u32 span) limit; nothing was rendered",
u32::MAX
),
span: Span { start: 0, end: 0 },
}
}
}
impl From<&aozora::Diagnostic> for Diagnostic {
fn from(d: &aozora::Diagnostic) -> Self {
let span = d.span();
Self {
severity: d.severity().into(),
source: d.source().into(),
code: d.code(),
message: d.to_string(),
span: Span {
start: span.start,
end: span.end,
},
}
}
}
impl From<aozora::Severity> for Severity {
fn from(s: aozora::Severity) -> Self {
match s {
aozora::Severity::Warning => Self::Warning,
aozora::Severity::Note => Self::Note,
_ => Self::Error,
}
}
}
impl From<aozora::DiagnosticSource> for DiagnosticSource {
fn from(s: aozora::DiagnosticSource) -> Self {
match s {
aozora::DiagnosticSource::Internal => Self::Internal,
_ => Self::Source,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn source_too_large_is_an_error_carrying_the_byte_counts() {
let d = Diagnostic::source_too_large(5_000_000_000);
assert_eq!(d.severity, Severity::Error);
assert_eq!(d.source, DiagnosticSource::Source);
assert_eq!(d.code, "aozora-md::source_too_large");
assert_eq!(d.span, Span { start: 0, end: 0 });
assert!(d.message.contains("5000000000"), "got: {}", d.message);
assert!(
d.message.contains(&u32::MAX.to_string()),
"got: {}",
d.message
);
}
#[test]
fn note_severity_maps_through_from_upstream() {
assert_eq!(Severity::from(aozora::Severity::Note), Severity::Note);
}
#[test]
fn internal_source_maps_through_from_upstream() {
assert_eq!(
DiagnosticSource::from(aozora::DiagnosticSource::Internal),
DiagnosticSource::Internal
);
}
}