1use core::fmt;
4
5#[derive(Debug, Clone, PartialEq, Eq)]
7#[non_exhaustive]
8pub struct CompileError {
9 pub kind: CompileErrorKind,
11 pub line_number: usize,
13}
14
15#[derive(Debug, Clone, PartialEq, Eq)]
17#[non_exhaustive]
18pub enum CompileErrorKind {
19 InvalidLengthGuard(String),
21 UnterminatedLengthGuard,
23 UnterminatedGroupSet,
25 EmptyGroupSet,
27 UnknownGroupName(String),
29 TokenAfterTrailingBoundary,
31 ExpectedDigitAfterBackslash,
33 IncreasingPriority {
35 base: u8,
37 min: u8,
39 },
40 BackslashWithoutDigit,
42 CaretNotFollowed,
44 EmptyGroupName,
46 NoLetters,
48 StrayCharacter(char),
50 ConflictingWeights,
52 WeightOutsideRun,
55 UnknownImport(String),
57}
58
59impl fmt::Display for CompileErrorKind {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 match self {
62 CompileErrorKind::InvalidLengthGuard(body) => {
63 write!(f, "Invalid length guard “[{body}]”")
64 }
65 CompileErrorKind::UnterminatedLengthGuard => write!(f, "Unterminated length guard"),
66 CompileErrorKind::UnterminatedGroupSet => write!(f, "Unterminated “{{” group set"),
67 CompileErrorKind::EmptyGroupSet => write!(f, "Empty “{{}}” group set"),
68 CompileErrorKind::UnknownGroupName(name) => {
69 write!(f, "Unknown Unicode Joining_Group name “{name}”")
70 }
71 CompileErrorKind::TokenAfterTrailingBoundary => {
72 write!(f, "Token after a trailing “.” boundary")
73 }
74 CompileErrorKind::ExpectedDigitAfterBackslash => {
75 write!(f, "Expected a digit after “\\”")
76 }
77 CompileErrorKind::IncreasingPriority { base, min } => {
78 write!(f, "Priority must not increase ({base}\\{min})")
79 }
80 CompileErrorKind::BackslashWithoutDigit => {
81 write!(f, "“\\” must follow a priority digit")
82 }
83 CompileErrorKind::CaretNotFollowed => {
84 write!(f, "“^” must be followed by “{{”, “@”, or “=”")
85 }
86 CompileErrorKind::EmptyGroupName => write!(f, "Empty group name"),
87 CompileErrorKind::NoLetters => write!(f, "Pattern has no letters"),
88 CompileErrorKind::StrayCharacter(ch) => write!(f, "Stray character {ch:?}"),
89 CompileErrorKind::ConflictingWeights => {
90 write!(f, "Conflicting weights at one connection")
91 }
92 CompileErrorKind::WeightOutsideRun => {
93 write!(f, "Weight outside the run at a “.” boundary")
94 }
95 CompileErrorKind::UnknownImport(name) => {
96 write!(f, "Unknown pattern set “{name}”")
97 }
98 }
99 }
100}
101
102impl fmt::Display for CompileError {
103 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104 write!(f, "line {}: {}", self.line_number, self.kind)
105 }
106}
107
108impl std::error::Error for CompileError {}