use std::fmt::{Debug, Display};
use vantage_expressions::{Expression, Expressive, ExpressiveEnum};
#[derive(Debug, Clone)]
pub struct Ternary<T: Debug + Display + Clone> {
condition: Expression<T>,
true_val: Expression<T>,
false_val: Expression<T>,
}
impl<T: Debug + Display + Clone> Ternary<T> {
pub fn new(
condition: impl Expressive<T>,
true_val: impl Expressive<T>,
false_val: impl Expressive<T>,
) -> Self {
Self {
condition: condition.expr(),
true_val: true_val.expr(),
false_val: false_val.expr(),
}
}
fn args(&self) -> Vec<ExpressiveEnum<T>> {
vec![
ExpressiveEnum::Nested(self.condition.clone()),
ExpressiveEnum::Nested(self.true_val.clone()),
ExpressiveEnum::Nested(self.false_val.clone()),
]
}
}
pub fn ternary<T: Debug + Display + Clone>(
condition: impl Expressive<T>,
true_val: impl Expressive<T>,
false_val: impl Expressive<T>,
) -> Ternary<T> {
Ternary::new(condition, true_val, false_val)
}
#[cfg(feature = "sqlite")]
impl Expressive<crate::sqlite::types::AnySqliteType>
for Ternary<crate::sqlite::types::AnySqliteType>
{
fn expr(&self) -> Expression<crate::sqlite::types::AnySqliteType> {
Expression::new("IIF({}, {}, {})", self.args())
}
}
#[cfg(feature = "mysql")]
impl Expressive<crate::mysql::types::AnyMysqlType> for Ternary<crate::mysql::types::AnyMysqlType> {
fn expr(&self) -> Expression<crate::mysql::types::AnyMysqlType> {
Expression::new("IF({}, {}, {})", self.args())
}
}
#[cfg(feature = "postgres")]
impl Expressive<crate::postgres::types::AnyPostgresType>
for Ternary<crate::postgres::types::AnyPostgresType>
{
fn expr(&self) -> Expression<crate::postgres::types::AnyPostgresType> {
Expression::new("CASE WHEN {} THEN {} ELSE {} END", self.args())
}
}