Skip to main content

vantage_sql/primitives/
iif.rs

1use std::fmt::{Debug, Display};
2
3use vantage_expressions::{Expression, Expressive, ExpressiveEnum};
4
5/// Vendor-aware conditional expression.
6///
7/// Renders as:
8/// - **SQLite:**     `IIF(cond, then, else)`
9/// - **MySQL:**      `IF(cond, then, else)`
10/// - **PostgreSQL:** `CASE WHEN cond THEN then ELSE else END`
11///
12/// # Examples
13///
14/// ```ignore
15/// Iif::new(
16///     ident("status").eq(mysql_expr!("{}", "completed")),
17///     mysql_expr!("'Done'"),
18///     mysql_expr!("'Active'"),
19/// )
20/// ```
21#[derive(Debug, Clone)]
22pub struct Iif<T: Debug + Display + Clone> {
23    condition: Expression<T>,
24    true_val: Expression<T>,
25    false_val: Expression<T>,
26}
27
28impl<T: Debug + Display + Clone> Iif<T> {
29    pub fn new(
30        condition: impl Expressive<T>,
31        true_val: impl Expressive<T>,
32        false_val: impl Expressive<T>,
33    ) -> Self {
34        Self {
35            condition: condition.expr(),
36            true_val: true_val.expr(),
37            false_val: false_val.expr(),
38        }
39    }
40}
41
42// -- SQLite: IIF(cond, then, else) --------------------------------------------
43
44#[cfg(feature = "sqlite")]
45impl Expressive<crate::sqlite::types::AnySqliteType> for Iif<crate::sqlite::types::AnySqliteType> {
46    fn expr(&self) -> Expression<crate::sqlite::types::AnySqliteType> {
47        Expression::new(
48            "IIF({}, {}, {})",
49            vec![
50                ExpressiveEnum::Nested(self.condition.clone()),
51                ExpressiveEnum::Nested(self.true_val.clone()),
52                ExpressiveEnum::Nested(self.false_val.clone()),
53            ],
54        )
55    }
56}
57
58// -- MySQL: IF(cond, then, else) ----------------------------------------------
59
60#[cfg(feature = "mysql")]
61impl Expressive<crate::mysql::types::AnyMysqlType> for Iif<crate::mysql::types::AnyMysqlType> {
62    fn expr(&self) -> Expression<crate::mysql::types::AnyMysqlType> {
63        Expression::new(
64            "IF({}, {}, {})",
65            vec![
66                ExpressiveEnum::Nested(self.condition.clone()),
67                ExpressiveEnum::Nested(self.true_val.clone()),
68                ExpressiveEnum::Nested(self.false_val.clone()),
69            ],
70        )
71    }
72}
73
74// -- PostgreSQL: CASE WHEN cond THEN then ELSE else END -----------------------
75
76#[cfg(feature = "postgres")]
77impl Expressive<crate::postgres::types::AnyPostgresType>
78    for Iif<crate::postgres::types::AnyPostgresType>
79{
80    fn expr(&self) -> Expression<crate::postgres::types::AnyPostgresType> {
81        Expression::new(
82            "CASE WHEN {} THEN {} ELSE {} END",
83            vec![
84                ExpressiveEnum::Nested(self.condition.clone()),
85                ExpressiveEnum::Nested(self.true_val.clone()),
86                ExpressiveEnum::Nested(self.false_val.clone()),
87            ],
88        )
89    }
90}