use std::fmt;
use std::ops::Range;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum Severity {
#[default]
Warning,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Diagnostic {
severity: Severity,
byte_range: Option<Range<usize>>,
detail: String,
}
impl Diagnostic {
pub fn warning(byte_range: Range<usize>, detail: impl Into<String>) -> Self {
Self {
severity: Severity::Warning,
byte_range: Some(byte_range),
detail: detail.into(),
}
}
pub fn unlocated(detail: impl Into<String>) -> Self {
Self {
severity: Severity::Warning,
byte_range: None,
detail: detail.into(),
}
}
pub const fn severity(&self) -> Severity {
self.severity
}
pub const fn byte_range(&self) -> Option<&Range<usize>> {
self.byte_range.as_ref()
}
pub fn detail(&self) -> &str {
&self.detail
}
}
impl fmt::Display for Diagnostic {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.byte_range {
Some(range) => write!(
formatter,
"warning at bytes {}..{}: {}",
range.start, range.end, self.detail
),
None => write!(formatter, "warning: {}", self.detail),
}
}
}