nginx_lint_parser/
error.rs

1//! Error types for the nginx configuration parser.
2//!
3//! [`ParseError`] covers failures during parsing (unexpected tokens, unclosed
4//! blocks, I/O errors). Each variant carries a [`Position`] so that error
5//! messages can point to the exact line and column in the source.
6
7use crate::ast::Position;
8use std::fmt;
9use thiserror::Error;
10
11/// An error that occurs during parsing.
12#[derive(Debug, Clone, Error)]
13pub enum ParseError {
14    /// The parser found a different token than expected.
15    #[error("Expected '{expected}' but found '{found}' at line {}, column {}", .position.line, .position.column)]
16    UnexpectedToken {
17        expected: String,
18        found: String,
19        position: Position,
20    },
21
22    /// A `{` was opened but never closed before end-of-file.
23    #[error("Unclosed block starting at line {}, column {}", .position.line, .position.column)]
24    UnclosedBlock { position: Position },
25
26    /// A file could not be read from disk.
27    #[error("Failed to read file: {0}")]
28    IoError(String),
29}
30
31impl ParseError {
32    /// Returns the source position where this error occurred, if available.
33    ///
34    /// Returns `None` only for [`IoError`](ParseError::IoError) which has no
35    /// source position.
36    pub fn position(&self) -> Option<Position> {
37        match self {
38            ParseError::UnexpectedToken { position, .. } => Some(*position),
39            ParseError::UnclosedBlock { position } => Some(*position),
40            ParseError::IoError(_) => None,
41        }
42    }
43}
44
45/// Result type alias for parser operations
46pub type ParseResult<T> = Result<T, ParseError>;
47
48/// Display implementation for user-friendly error messages
49impl fmt::Display for Position {
50    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51        write!(f, "{}:{}", self.line, self.column)
52    }
53}