rjango 0.1.1

A full-stack Rust backend framework inspired by Django
Documentation
use sea_orm::sea_query::{Alias, Func, SimpleExpr};

use super::custom_function;

/// SQL CAST(expr AS type_name).
pub fn cast(expr: SimpleExpr, type_name: &str) -> SimpleExpr {
    Func::cast_as(expr, Alias::new(type_name)).into()
}

/// SQL COALESCE(a, b, ...) — returns the first non-null value.
pub fn coalesce(exprs: Vec<SimpleExpr>) -> SimpleExpr {
    assert!(!exprs.is_empty(), "COALESCE requires at least one argument");
    Func::coalesce(exprs).into()
}

/// SQL GREATEST(a, b).
pub fn greatest(left: SimpleExpr, right: SimpleExpr) -> SimpleExpr {
    Func::greatest([left, right]).into()
}

/// SQL LEAST(a, b).
pub fn least(left: SimpleExpr, right: SimpleExpr) -> SimpleExpr {
    Func::least([left, right]).into()
}

/// SQL NULLIF(a, b).
pub fn nullif(left: SimpleExpr, right: SimpleExpr) -> SimpleExpr {
    custom_function("NULLIF", vec![left, right])
}

#[cfg(test)]
mod tests {
    use super::{cast, coalesce, greatest, least, nullif};
    use sea_orm::sea_query::{Alias, Expr, PostgresQueryBuilder, Query, SimpleExpr};

    fn column(name: &str) -> SimpleExpr {
        Expr::col(Alias::new(name)).into()
    }

    fn render_select_expr(expr: SimpleExpr, alias: &str) -> String {
        Query::select()
            .expr_as(expr, Alias::new(alias))
            .from(Alias::new("widgets"))
            .to_owned()
            .to_string(PostgresQueryBuilder)
    }

    #[test]
    fn test_cast() {
        let sql = render_select_expr(cast(column("age"), "TEXT"), "age_text");
        assert!(sql.contains("CAST"), "expected CAST SQL, got: {sql}");
        assert!(
            sql.contains("TEXT"),
            "expected TEXT cast target, got: {sql}"
        );
    }

    #[test]
    fn test_coalesce() {
        let sql = render_select_expr(
            coalesce(vec![
                column("nickname"),
                column("name"),
                Expr::value("fallback"),
            ]),
            "screen_name",
        );
        assert!(
            sql.contains("COALESCE"),
            "expected COALESCE SQL, got: {sql}"
        );
    }

    #[test]
    fn test_greatest() {
        let sql = render_select_expr(
            greatest(column("priority"), Expr::value(10)),
            "top_priority",
        );
        assert!(
            sql.contains("GREATEST"),
            "expected GREATEST SQL, got: {sql}"
        );
    }

    #[test]
    fn test_least() {
        let sql = render_select_expr(
            least(column("priority"), Expr::value(10)),
            "bounded_priority",
        );
        assert!(sql.contains("LEAST"), "expected LEAST SQL, got: {sql}");
    }

    #[test]
    fn test_nullif() {
        let sql = render_select_expr(
            nullif(column("status"), Expr::value("archived")),
            "active_status",
        );
        assert!(sql.contains("NULLIF"), "expected NULLIF SQL, got: {sql}");
    }
}