taitan_orm_parser/template_parser/structs/
simple_expr.rs

1use crate::template_parser::structs::atomic::Atomic;
2use crate::template_parser::structs::operators::Operator;
3use crate::template_parser::to_sql::{SqlSegment, ToSqlSegment};
4use nom::branch::alt;
5use nom::character::complete::multispace0;
6use nom::combinator::{map, opt};
7use nom::sequence::preceded;
8use nom::IResult;
9use tracing::debug;
10
11#[derive(Debug, PartialEq, Clone)]
12pub enum SimpleExpr {
13    Single(Atomic),
14    Binary {
15        left: Atomic,
16        op: Operator,
17        right: Atomic,
18    },
19}
20
21impl SimpleExpr {
22    pub fn parse(input: &str) -> IResult<&str, SimpleExpr> {
23        alt((parse_binary_expr, map(Atomic::parse, SimpleExpr::Single)))(input)
24    }
25}
26
27impl ToSqlSegment for SimpleExpr {
28    fn gen_sql_segments(&self) -> Vec<SqlSegment> {
29        match self {
30            SimpleExpr::Single(atomic) => vec![atomic.gen_sql_segment()],
31            SimpleExpr::Binary { left, op, right } => {
32                let segments = vec![
33                    left.gen_sql_segment(),
34                    SqlSegment::Simple(op.to_string()),
35                    right.gen_sql_segment(),
36                ];
37                segments
38            }
39        }
40    }
41}
42
43fn parse_binary_expr(input: &str) -> IResult<&str, SimpleExpr> {
44    debug!("SimpleExpr parse({})", input);
45    let (input, left) = preceded(multispace0, Atomic::parse)(input)?; // 解析左操作数
46    let (input, op) = preceded(multispace0, Operator::parse)(input)?; // 解析操作符
47    let (input, right) = preceded(multispace0, Atomic::parse)(input)?; // 解析右操作数
48    let parsed = SimpleExpr::Binary { left, op, right };
49    debug!("SimpleExpr parse -> {:?}", parsed);
50    debug!("SimpleExpr parse -> remaining: {}", input);
51    Ok((input, parsed))
52}
53
54#[cfg(test)]
55mod simple_expr_test {
56    use crate::template_parser::structs::operators::CompareOp;
57    use super::*;
58    use crate::template_parser::structs::variable::{Variable, VariableChain};
59    #[test]
60    fn test_simple_expr_parse() {
61        // let template = "a = b";
62        // let (_, parsed) = SimpleExpr::parse(template).unwrap();
63        // let expected = SimpleExpr::Binary {
64        //     left: Atomic::VariableChain(VariableChain::new(vec![Variable::Simple(
65        //         "a".to_string(),
66        //     )])),
67        //     op: Operator::Compare(ComparisonOp::Equal),
68        //     right: Atomic::VariableChain(VariableChain::new(vec![Variable::Simple(
69        //         "b".to_string(),
70        //     )])),
71        // };
72        // assert_eq!(parsed, expected);
73    }
74
75    #[test]
76    fn test_simple_expr_parse_02() {
77        // let template = "a = b and c > d";
78        // let (_, parsed) = SimpleExpr::parse(template).unwrap();
79        //
80        // let expected = SimpleExpr::Binary {
81        //     left: Atomic::VariableChain(VariableChain::new(vec![Variable::Simple(
82        //         "a".to_string(),
83        //     )])),
84        //     op: Operator::Compare(ComparisonOp::Equal),
85        //     right: Atomic::VariableChain(VariableChain::new(vec![Variable::Simple(
86        //         "b".to_string(),
87        //     )])),
88        // };
89        // // assert_eq!(remaining, "select * from users");
90        // assert_eq!(parsed, expected);
91    }
92}