Skip to main content

gobject_ast/model/expression/
binary.rs

1use serde::Serialize;
2
3use crate::model::{BinaryOp, Expression, SourceLocation};
4
5#[derive(Debug, Clone, Serialize)]
6pub struct BinaryExpression {
7    pub left: Box<Expression>,
8    pub operator: BinaryOp,
9    pub right: Box<Expression>,
10    pub location: SourceLocation,
11}
12
13impl BinaryExpression {
14    /// Check if this is a NULL comparison (x != NULL, x == NULL, etc.)
15    pub fn is_null_check(&self) -> bool {
16        matches!(self.operator, BinaryOp::Equal | BinaryOp::NotEqual)
17            && (self.left.is_null() || self.right.is_null())
18    }
19
20    /// Extract the variable being compared in expressions like `x != 0`, `x >
21    /// 0`, `0 < x`, `x != NULL`, `NULL != x`
22    pub fn extract_compared_variable(&self) -> Option<&str> {
23        let left_is_zero = self.left.is_zero();
24        let right_is_zero = self.right.is_zero();
25        let left_is_null = self.left.is_null();
26        let right_is_null = self.right.is_null();
27
28        match self.operator {
29            BinaryOp::NotEqual | BinaryOp::Equal | BinaryOp::Greater | BinaryOp::GreaterEqual => {
30                if right_is_zero || right_is_null {
31                    self.left.extract_variable_name()
32                } else if left_is_zero || left_is_null {
33                    self.right.extract_variable_name()
34                } else {
35                    None
36                }
37            }
38            BinaryOp::Less | BinaryOp::LessEqual => {
39                if left_is_zero {
40                    self.right.extract_variable_name()
41                } else if right_is_zero {
42                    self.left.extract_variable_name()
43                } else {
44                    None
45                }
46            }
47            _ => None,
48        }
49    }
50}