dsq_parser/
error.rs

1//! Error types for the DSQ parser
2
3use std::fmt;
4
5/// Errors that can occur during parsing
6#[derive(Debug, Clone, PartialEq)]
7pub enum ParseError {
8    /// Unexpected token encountered
9    UnexpectedToken {
10        /// The unexpected token
11        found: String,
12        /// Expected tokens (if known)
13        expected: Vec<String>,
14        /// Position in the input
15        position: usize,
16    },
17
18    /// Invalid syntax
19    InvalidSyntax {
20        /// Description of the syntax error
21        message: String,
22        /// Position in the input
23        position: usize,
24    },
25
26    /// Unterminated string literal
27    UnterminatedString {
28        /// Position where the string starts
29        position: usize,
30    },
31
32    /// Invalid number literal
33    InvalidNumber {
34        /// The invalid number string
35        number: String,
36        /// Position in the input
37        position: usize,
38    },
39
40    /// Unknown function name
41    UnknownFunction {
42        /// The function name
43        name: String,
44        /// Position in the input
45        position: usize,
46    },
47
48    /// Invalid field access
49    InvalidFieldAccess {
50        /// The invalid field string
51        field: String,
52        /// Position in the input
53        position: usize,
54    },
55
56    /// Mismatched parentheses or brackets
57    MismatchedBrackets {
58        /// The opening bracket
59        opening: char,
60        /// Position of the opening bracket
61        position: usize,
62    },
63
64    /// Empty input
65    EmptyInput,
66
67    /// General parsing error
68    General {
69        /// Error message
70        message: String,
71    },
72
73    /// Nom parsing error (internal)
74    NomError {
75        /// Error message from nom
76        message: String,
77    },
78}
79
80impl fmt::Display for ParseError {
81    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82        match self {
83            ParseError::UnexpectedToken {
84                found,
85                expected,
86                position,
87            } => {
88                write!(f, "Unexpected token '{}' at position {}", found, position)?;
89                if !expected.is_empty() {
90                    write!(f, ". Expected one of: {}", expected.join(", "))?;
91                }
92                Ok(())
93            }
94            ParseError::InvalidSyntax { message, position } => {
95                write!(f, "Invalid syntax at position {}: {}", position, message)
96            }
97            ParseError::UnterminatedString { position } => {
98                write!(
99                    f,
100                    "Unterminated string literal starting at position {}",
101                    position
102                )
103            }
104            ParseError::InvalidNumber { number, position } => {
105                write!(f, "Invalid number '{}' at position {}", number, position)
106            }
107            ParseError::UnknownFunction { name, position } => {
108                write!(f, "Unknown function '{}' at position {}", name, position)
109            }
110            ParseError::InvalidFieldAccess { field, position } => {
111                write!(
112                    f,
113                    "Invalid field access '{}' at position {}",
114                    field, position
115                )
116            }
117            ParseError::MismatchedBrackets { opening, position } => {
118                write!(
119                    f,
120                    "Mismatched brackets. Opening '{}' at position {} has no matching close",
121                    opening, position
122                )
123            }
124            ParseError::EmptyInput => write!(f, "Empty input"),
125            ParseError::General { message } => write!(f, "{}", message),
126            ParseError::NomError { message } => write!(f, "Nom error: {}", message),
127        }
128    }
129}
130
131impl std::error::Error for ParseError {}
132
133/// Result type for parsing operations
134pub type Result<T> = std::result::Result<T, ParseError>;
135
136impl From<nom::Err<nom::error::Error<&str>>> for ParseError {
137    fn from(err: nom::Err<nom::error::Error<&str>>) -> Self {
138        match err {
139            nom::Err::Error(e) | nom::Err::Failure(e) => {
140                // Position calculation is not accurate without original input length
141                let position = 0;
142                ParseError::InvalidSyntax {
143                    message: format!("Parse error: {}", e.code.description()),
144                    position,
145                }
146            }
147            nom::Err::Incomplete(_) => ParseError::General {
148                message: "Incomplete input".to_string(),
149            },
150        }
151    }
152}