use crate::commands::{
ConstructStatus, LAYOUT_PENDING_TRACKING, TIER2_TRACKING, UNTIERED_TRACKING, construct_status,
};
use crate::node::Span;
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum MathError {
UnsupportedCommand {
name: String,
span: Span,
},
Malformed {
what: String,
at: usize,
},
UnmappedChar {
ch: char,
span: Span,
},
}
impl MathError {
#[must_use]
pub fn span(&self) -> Span {
match self {
Self::UnsupportedCommand { span, .. } | Self::UnmappedChar { span, .. } => *span,
Self::Malformed { at, .. } => Span::new(*at, *at),
}
}
#[must_use]
pub fn unsupported_construct(&self) -> Option<&str> {
match self {
Self::UnsupportedCommand { name, .. } => Some(name),
_ => None,
}
}
}
impl core::fmt::Display for MathError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::UnsupportedCommand { name, span } => match construct_status(name) {
ConstructStatus::UnsupportedT2 => write!(
f,
"`{name}` is not yet supported; tier T2, tracked at {TIER2_TRACKING} \
(bytes {}..{})",
span.start, span.end
),
ConstructStatus::Supported => write!(
f,
"`{name}` parses, but its layout is not yet implemented; tracked at \
{LAYOUT_PENDING_TRACKING} (bytes {}..{})",
span.start, span.end
),
ConstructStatus::Unknown => write!(
f,
"`{name}` is not supported; untiered (not observed in the G0-4 corpus), \
report at {UNTIERED_TRACKING} (bytes {}..{})",
span.start, span.end
),
},
Self::Malformed { what, at } => {
write!(f, "malformed mathematics at byte {at}: {what}")
}
Self::UnmappedChar { ch, span } => write!(
f,
"character '{ch}' (U+{:04X}) has no glyph in the bundled math faces \
(bytes {}..{})",
*ch as u32, span.start, span.end
),
}
}
}
impl std::error::Error for MathError {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn tier2_message_format_is_stable() {
let err = MathError::UnsupportedCommand {
name: r"\dx".to_owned(),
span: Span::new(3, 6),
};
assert_eq!(
err.to_string(),
"`\\dx` is not yet supported; tier T2, tracked at franken_manim fm-j5t \
(the tier-2 construct program) (bytes 3..6)"
);
}
#[test]
fn untiered_message_format_is_stable() {
let err = MathError::UnsupportedCommand {
name: r"\notacommand".to_owned(),
span: Span::new(0, 12),
};
assert_eq!(
err.to_string(),
"`\\notacommand` is not supported; untiered (not observed in the G0-4 corpus), \
report at https://github.com/Dicklesworthstone/franken_manim/issues (bytes 0..12)"
);
}
#[test]
fn malformed_message_format_is_stable() {
let err = MathError::Malformed {
what: "unmatched '}'".to_owned(),
at: 7,
};
assert_eq!(
err.to_string(),
"malformed mathematics at byte 7: unmatched '}'"
);
}
}