use core::fmt;
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub struct CompileError {
pub kind: CompileErrorKind,
pub line_number: usize,
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum CompileErrorKind {
InvalidLengthGuard(String),
UnterminatedLengthGuard,
UnterminatedGroupSet,
EmptyGroupSet,
UnknownGroupName(String),
TokenAfterTrailingBoundary,
ExpectedDigitAfterBackslash,
IncreasingPriority {
base: u8,
min: u8,
},
BackslashWithoutDigit,
CaretNotFollowed,
EmptyGroupName,
NoLetters,
StrayCharacter(char),
ConflictingWeights,
WeightOutsideRun,
UnknownImport(String),
}
impl fmt::Display for CompileErrorKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
CompileErrorKind::InvalidLengthGuard(body) => {
write!(f, "Invalid length guard “[{body}]”")
}
CompileErrorKind::UnterminatedLengthGuard => write!(f, "Unterminated length guard"),
CompileErrorKind::UnterminatedGroupSet => write!(f, "Unterminated “{{” group set"),
CompileErrorKind::EmptyGroupSet => write!(f, "Empty “{{}}” group set"),
CompileErrorKind::UnknownGroupName(name) => {
write!(f, "Unknown Unicode Joining_Group name “{name}”")
}
CompileErrorKind::TokenAfterTrailingBoundary => {
write!(f, "Token after a trailing “.” boundary")
}
CompileErrorKind::ExpectedDigitAfterBackslash => {
write!(f, "Expected a digit after “\\”")
}
CompileErrorKind::IncreasingPriority { base, min } => {
write!(f, "Priority must not increase ({base}\\{min})")
}
CompileErrorKind::BackslashWithoutDigit => {
write!(f, "“\\” must follow a priority digit")
}
CompileErrorKind::CaretNotFollowed => {
write!(f, "“^” must be followed by “{{”, “@”, or “=”")
}
CompileErrorKind::EmptyGroupName => write!(f, "Empty group name"),
CompileErrorKind::NoLetters => write!(f, "Pattern has no letters"),
CompileErrorKind::StrayCharacter(ch) => write!(f, "Stray character {ch:?}"),
CompileErrorKind::ConflictingWeights => {
write!(f, "Conflicting weights at one connection")
}
CompileErrorKind::WeightOutsideRun => {
write!(f, "Weight outside the run at a “.” boundary")
}
CompileErrorKind::UnknownImport(name) => {
write!(f, "Unknown pattern set “{name}”")
}
}
}
}
impl fmt::Display for CompileError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "line {}: {}", self.line_number, self.kind)
}
}
impl std::error::Error for CompileError {}