quaint_forked/ast/
conditions.rs

1use crate::ast::*;
2
3/// Tree structures and leaves for condition building.
4#[derive(Debug, PartialEq, Clone)]
5pub enum ConditionTree<'a> {
6    /// `(left_expression AND right_expression)`
7    And(Vec<Expression<'a>>),
8    /// `(left_expression OR right_expression)`
9    Or(Vec<Expression<'a>>),
10    /// `(NOT expression)`
11    Not(Box<Expression<'a>>),
12    /// A single expression leaf
13    Single(Box<Expression<'a>>),
14    /// A leaf that does nothing to the condition, `1=1`
15    NoCondition,
16    /// A leaf that cancels the condition, `1=0`
17    NegativeCondition,
18}
19
20impl<'a> ConditionTree<'a> {
21    // Finds all possible comparisons between a tuple and a select. If returning
22    // a vector of CTEs, they should be handled by the calling party.
23    #[cfg(feature = "mssql")]
24    pub(crate) fn convert_tuple_selects_to_ctes(self, level: &mut usize) -> (Self, Vec<CommonTableExpression<'a>>) {
25        fn convert_many<'a>(
26            exprs: Vec<Expression<'a>>,
27            level: &mut usize,
28        ) -> (Vec<Expression<'a>>, Vec<CommonTableExpression<'a>>) {
29            let mut converted = Vec::with_capacity(exprs.len());
30            let mut result_ctes = Vec::new();
31
32            for expr in exprs.into_iter() {
33                let (expr, ctes) = expr.convert_tuple_selects_to_ctes(level);
34
35                converted.push(expr);
36                result_ctes.extend(ctes);
37            }
38
39            (converted, result_ctes)
40        }
41
42        match self {
43            Self::Single(expr) => {
44                let (expr, ctes) = expr.convert_tuple_selects_to_ctes(level);
45
46                (Self::single(expr), ctes)
47            }
48            Self::Not(expr) => {
49                let (expr, ctes) = expr.convert_tuple_selects_to_ctes(level);
50
51                (expr.not(), ctes)
52            }
53            Self::And(exprs) => {
54                let (converted, ctes) = convert_many(exprs, level);
55                (Self::And(converted), ctes)
56            }
57            Self::Or(exprs) => {
58                let (converted, ctes) = convert_many(exprs, level);
59                (Self::Or(converted), ctes)
60            }
61            tree => (tree, Vec::new()),
62        }
63    }
64
65    /// An `AND` statement, is true when both sides are true.
66    pub fn and<E>(mut self, other: E) -> ConditionTree<'a>
67    where
68        E: Into<Expression<'a>>,
69    {
70        match self {
71            Self::And(ref mut conditions) => {
72                conditions.push(other.into());
73                self
74            }
75            Self::Single(expr) => Self::And(vec![*expr, other.into()]),
76            _ => Self::And(vec![Expression::from(self), other.into()]),
77        }
78    }
79
80    /// An `OR` statement, is true when one side is true.
81    pub fn or<E>(mut self, other: E) -> ConditionTree<'a>
82    where
83        E: Into<Expression<'a>>,
84    {
85        match self {
86            Self::Or(ref mut conditions) => {
87                conditions.push(other.into());
88                self
89            }
90            Self::Single(expr) => Self::Or(vec![*expr, other.into()]),
91            _ => Self::Or(vec![Expression::from(self), other.into()]),
92        }
93    }
94
95    /// A `NOT` statement, is true when the expression is false.
96    pub fn not<E>(left: E) -> ConditionTree<'a>
97    where
98        E: Into<Expression<'a>>,
99    {
100        ConditionTree::Not(Box::new(left.into()))
101    }
102
103    /// A single leaf, is true when the expression is true.
104    pub fn single<E>(left: E) -> ConditionTree<'a>
105    where
106        E: Into<Expression<'a>>,
107    {
108        ConditionTree::Single(Box::new(left.into()))
109    }
110
111    /// Inverts the entire condition tree if condition is met.
112    pub fn invert_if(self, invert: bool) -> ConditionTree<'a> {
113        if invert {
114            self.not()
115        } else {
116            self
117        }
118    }
119}
120
121impl<'a> Default for ConditionTree<'a> {
122    fn default() -> Self {
123        ConditionTree::NoCondition
124    }
125}
126
127impl<'a> From<ConditionTree<'a>> for Expression<'a> {
128    fn from(ct: ConditionTree<'a>) -> Self {
129        Expression {
130            kind: ExpressionKind::ConditionTree(ct),
131            alias: None,
132        }
133    }
134}
135
136impl<'a> From<Select<'a>> for ConditionTree<'a> {
137    fn from(sel: Select<'a>) -> Self {
138        let exp = Expression {
139            kind: ExpressionKind::Value(Box::new(sel.into())),
140            alias: None,
141        };
142
143        ConditionTree::single(exp)
144    }
145}