espresso_logic/expression/
error.rs1use std::fmt;
4use std::io;
5use std::sync::Arc;
6
7#[derive(Debug, Clone, PartialEq, Eq)]
11pub enum ExpressionParseError {
12 InvalidSyntax {
14 message: Arc<str>,
16 input: Arc<str>,
18 position: Option<usize>,
20 },
21}
22
23impl fmt::Display for ExpressionParseError {
24 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25 match self {
26 ExpressionParseError::InvalidSyntax {
27 message,
28 input,
29 position,
30 } => {
31 if let Some(pos) = position {
32 write!(
33 f,
34 "Failed to parse boolean expression at position {}: {}. Input: {:?}",
35 pos, message, input
36 )
37 } else {
38 write!(
39 f,
40 "Failed to parse boolean expression: {}. Input: {:?}",
41 message, input
42 )
43 }
44 }
45 }
46 }
47}
48
49impl std::error::Error for ExpressionParseError {}
50
51impl From<ExpressionParseError> for io::Error {
52 fn from(err: ExpressionParseError) -> Self {
53 io::Error::new(io::ErrorKind::InvalidData, err)
54 }
55}
56
57#[derive(Debug)]
61pub enum ParseBoolExprError {
62 Parse(ExpressionParseError),
64}
65
66impl fmt::Display for ParseBoolExprError {
67 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68 match self {
69 ParseBoolExprError::Parse(e) => write!(f, "{}", e),
70 }
71 }
72}
73
74impl std::error::Error for ParseBoolExprError {
75 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
76 match self {
77 ParseBoolExprError::Parse(e) => Some(e),
78 }
79 }
80}
81
82impl From<ExpressionParseError> for ParseBoolExprError {
83 fn from(err: ExpressionParseError) -> Self {
84 ParseBoolExprError::Parse(err)
85 }
86}
87
88impl From<ParseBoolExprError> for io::Error {
89 fn from(err: ParseBoolExprError) -> Self {
90 match err {
91 ParseBoolExprError::Parse(e) => io::Error::new(io::ErrorKind::InvalidData, e),
92 }
93 }
94}
95
96#[cfg(test)]
97mod tests {
98 use super::*;
99
100 #[test]
101 fn test_expression_parse_error_with_position() {
102 let err = ExpressionParseError::InvalidSyntax {
103 message: Arc::from("unexpected token"),
104 input: Arc::from("a * b ++"),
105 position: Some(6),
106 };
107 let msg = err.to_string();
108 assert!(msg.contains("position 6"));
109 assert!(msg.contains("unexpected token"));
110 }
111
112 #[test]
113 fn test_expression_parse_error_without_position() {
114 let err = ExpressionParseError::InvalidSyntax {
115 message: Arc::from("unexpected end"),
116 input: Arc::from("a * b +"),
117 position: None,
118 };
119 let msg = err.to_string();
120 assert!(!msg.contains("position"));
121 assert!(msg.contains("unexpected end"));
122 }
123
124 #[test]
125 fn test_parse_bool_expr_error() {
126 let parse_err = ExpressionParseError::InvalidSyntax {
127 message: Arc::from("test"),
128 input: Arc::from("bad input"),
129 position: Some(5),
130 };
131 let bool_err: ParseBoolExprError = parse_err.into();
132 assert!(matches!(bool_err, ParseBoolExprError::Parse(_)));
133 }
134
135 #[test]
136 fn test_expression_parse_error_to_io_error() {
137 let err = ExpressionParseError::InvalidSyntax {
138 message: Arc::from("test"),
139 input: Arc::from("bad input"),
140 position: Some(5),
141 };
142 let io_err: io::Error = err.into();
143 assert_eq!(io_err.kind(), io::ErrorKind::InvalidData);
144 }
145
146 #[test]
147 fn test_parse_bool_expr_error_to_io_error() {
148 let parse_err = ExpressionParseError::InvalidSyntax {
149 message: Arc::from("test"),
150 input: Arc::from("bad input"),
151 position: Some(5),
152 };
153 let bool_err = ParseBoolExprError::Parse(parse_err);
154 let io_err: io::Error = bool_err.into();
155 assert_eq!(io_err.kind(), io::ErrorKind::InvalidData);
156 }
157}