use alloc::string::String;
use core::fmt;
#[derive(Debug, Clone, PartialEq)]
pub enum A2lError {
UnterminatedString {
line: usize,
},
UnterminatedComment {
line: usize,
},
InvalidNumber {
text: String,
line: usize,
},
InvalidAddress {
value: f64,
line: usize,
},
UnexpectedEof {
context: &'static str,
},
UnexpectedToken {
expected: &'static str,
got: String,
line: usize,
},
InvalidDatatype {
text: String,
line: usize,
},
InvalidCharType {
text: String,
line: usize,
},
InvalidConversionType {
text: String,
line: usize,
},
UnterminatedBlock {
block: String,
line: usize,
},
BlockMismatch {
opened: String,
closed: String,
line: usize,
},
MissingProject,
DepthLimitExceeded {
line: usize,
},
}
impl A2lError {
#[must_use]
pub fn line(&self) -> Option<usize> {
Some(match self {
Self::UnterminatedString { line }
| Self::UnterminatedComment { line }
| Self::InvalidNumber { line, .. }
| Self::InvalidAddress { line, .. }
| Self::UnexpectedToken { line, .. }
| Self::InvalidDatatype { line, .. }
| Self::InvalidCharType { line, .. }
| Self::InvalidConversionType { line, .. }
| Self::UnterminatedBlock { line, .. }
| Self::BlockMismatch { line, .. }
| Self::DepthLimitExceeded { line } => *line,
Self::UnexpectedEof { .. } | Self::MissingProject => return None,
})
}
}
impl fmt::Display for A2lError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::UnterminatedString { line } => write!(f, "line {line}: unterminated string"),
Self::UnterminatedComment { line } => write!(f, "line {line}: unterminated /* comment"),
Self::InvalidNumber { text, line } => {
write!(f, "line {line}: invalid number `{text}`")
}
Self::InvalidAddress { value, line } => {
write!(f, "line {line}: value {value} is not a 32-bit ECU address")
}
Self::UnexpectedEof { context } => {
write!(f, "unexpected end of input: expected {context}")
}
Self::UnexpectedToken {
expected,
got,
line,
} => {
write!(f, "line {line}: expected {expected}, found `{got}`")
}
Self::InvalidDatatype { text, line } => {
write!(f, "line {line}: unknown ASAP2 datatype `{text}`")
}
Self::InvalidCharType { text, line } => {
write!(f, "line {line}: unknown CHARACTERISTIC type `{text}`")
}
Self::InvalidConversionType { text, line } => {
write!(
f,
"line {line}: unknown COMPU_METHOD conversion type `{text}`"
)
}
Self::UnterminatedBlock { block, line } => {
write!(
f,
"line {line}: `/begin {block}` without matching `/end {block}`"
)
}
Self::BlockMismatch {
opened,
closed,
line,
} => {
write!(f, "line {line}: `/end {closed}` closes `/begin {opened}`")
}
Self::MissingProject => f.write_str("no `/begin PROJECT` block found"),
Self::DepthLimitExceeded { line } => {
write!(f, "line {line}: block nesting exceeds the parser limit")
}
}
}
}
impl core::error::Error for A2lError {}