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#[cfg(feature = "sqlite")]
43impl Expressive<crate::sqlite::types::AnySqliteType> for Iif<crate::sqlite::types::AnySqliteType> {
44    fn expr(&self) -> Expression<crate::sqlite::types::AnySqliteType> {
45        Expression::new(
46            "IIF({}, {}, {})",
47            vec![
48                ExpressiveEnum::Nested(self.condition.clone()),
49                ExpressiveEnum::Nested(self.true_val.clone()),
50                ExpressiveEnum::Nested(self.false_val.clone()),
51            ],
52        )
53    }
54}
55
56#[cfg(feature = "mysql")]
57impl Expressive<crate::mysql::types::AnyMysqlType> for Iif<crate::mysql::types::AnyMysqlType> {
58    fn expr(&self) -> Expression<crate::mysql::types::AnyMysqlType> {
59        Expression::new(
60            "IF({}, {}, {})",
61            vec![
62                ExpressiveEnum::Nested(self.condition.clone()),
63                ExpressiveEnum::Nested(self.true_val.clone()),
64                ExpressiveEnum::Nested(self.false_val.clone()),
65            ],
66        )
67    }
68}
69
70#[cfg(feature = "postgres")]
71impl Expressive<crate::postgres::types::AnyPostgresType>
72    for Iif<crate::postgres::types::AnyPostgresType>
73{
74    fn expr(&self) -> Expression<crate::postgres::types::AnyPostgresType> {
75        Expression::new(
76            "CASE WHEN {} THEN {} ELSE {} END",
77            vec![
78                ExpressiveEnum::Nested(self.condition.clone()),
79                ExpressiveEnum::Nested(self.true_val.clone()),
80                ExpressiveEnum::Nested(self.false_val.clone()),
81            ],
82        )
83    }
84}