Skip to main content

jia_parse/
error.rs

1//! Error types for the PDDL parser.
2//!
3//! Provides [`ParseError`] with a human-readable message and a [`Span`] that pinpoints
4//! the exact location (byte offset, line, column) in the source text where the error occurred.
5
6use std::fmt;
7
8/// A source location in the PDDL input text.
9///
10/// Used throughout the parser and lexer to attach position information to tokens
11/// and error messages. Both `line` and `col` are 1-based.
12#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize)]
13pub struct Span {
14    /// Byte offset from the start of the input.
15    pub offset: usize,
16    /// 1-based line number.
17    pub line: usize,
18    /// 1-based column number.
19    pub col: usize,
20}
21
22impl Span {
23    /// Create a new source span.
24    ///
25    /// # Arguments
26    ///
27    /// * `offset` - Byte offset from the start of the input
28    /// * `line` - 1-based line number
29    /// * `col` - 1-based column number
30    pub fn new(offset: usize, line: usize, col: usize) -> Self {
31        Self { offset, line, col }
32    }
33}
34
35impl fmt::Display for Span {
36    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37        write!(f, "{}:{}", self.line, self.col)
38    }
39}
40
41/// A parse error with a human-readable message and source location.
42///
43/// Displayed as `"parse error at <line>:<col>: <message>"`.
44/// Implements `std::error::Error` for integration with `anyhow` / `?` chains.
45#[derive(Debug, Clone, PartialEq, Eq)]
46pub struct ParseError {
47    /// What went wrong.
48    pub message: String,
49    /// Where in the source text it went wrong.
50    pub span: Span,
51}
52
53impl ParseError {
54    /// Create a new parse error.
55    ///
56    /// # Arguments
57    ///
58    /// * `message` - Human-readable description of the error
59    /// * `span` - Source location where the error was detected
60    pub fn new(message: impl Into<String>, span: Span) -> Self {
61        Self {
62            message: message.into(),
63            span,
64        }
65    }
66}
67
68impl fmt::Display for ParseError {
69    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70        write!(f, "parse error at {}: {}", self.span, self.message)
71    }
72}
73
74impl std::error::Error for ParseError {}