1use std::fmt;
4
5#[derive(Debug, Clone, PartialEq)]
7pub enum ParseError {
8 UnexpectedToken {
10 found: String,
12 expected: Vec<String>,
14 position: usize,
16 },
17
18 InvalidSyntax {
20 message: String,
22 position: usize,
24 },
25
26 UnterminatedString {
28 position: usize,
30 },
31
32 InvalidNumber {
34 number: String,
36 position: usize,
38 },
39
40 UnknownFunction {
42 name: String,
44 position: usize,
46 },
47
48 InvalidFieldAccess {
50 field: String,
52 position: usize,
54 },
55
56 MismatchedBrackets {
58 opening: char,
60 position: usize,
62 },
63
64 EmptyInput,
66
67 General {
69 message: String,
71 },
72
73 NomError {
75 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
133pub 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 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}