espresso_logic/expression/
parser.rs1use super::error::{ExpressionParseError, ParseBoolExprError};
4use super::BoolExpr;
5use std::sync::Arc;
6
7#[allow(clippy::all)]
9mod parser_impl {
10 #![allow(clippy::all)]
11 #![allow(dead_code)]
12 #![allow(unused_variables)]
13 #![allow(unused_imports)]
14 #![allow(non_snake_case)]
15 #![allow(non_camel_case_types)]
16 #![allow(non_upper_case_globals)]
17 include!(concat!(env!("OUT_DIR"), "/expression/bool_expr.rs"));
18}
19
20impl BoolExpr {
21 pub fn parse(input: &str) -> Result<Self, ParseBoolExprError> {
30 parser_impl::ExprParser::new().parse(input).map_err(|e| {
31 let message = e.to_string();
32 let position = extract_position_from_error(&message);
34 ExpressionParseError::InvalidSyntax {
35 message: Arc::from(message.as_str()),
36 input: Arc::from(input),
37 position,
38 }
39 .into()
40 })
41 }
42}
43
44fn extract_position_from_error(error_msg: &str) -> Option<usize> {
49 if let Some(col_idx) = error_msg.find("column ") {
54 let after_col = &error_msg[col_idx + 7..];
55 if let Some(end_idx) = after_col.find(|c: char| !c.is_ascii_digit()) {
56 if let Ok(col) = after_col[..end_idx].parse::<usize>() {
57 return Some(col.saturating_sub(1)); }
59 }
60 }
61
62 if let Some(at_idx) = error_msg.rfind(" at ") {
64 let after_at = &error_msg[at_idx + 4..];
65 if let Some(end_idx) = after_at.find(|c: char| !c.is_ascii_digit()) {
66 if let Ok(pos) = after_at[..end_idx].parse::<usize>() {
67 return Some(pos);
68 }
69 }
70 if let Ok(pos) = after_at.trim().parse::<usize>() {
72 return Some(pos);
73 }
74 }
75
76 None
77}