kali 0.1.0

A query builder and orm-ish crate built on sqlx
Documentation
use super::value::Value;
use crate::column::Column;
use std::borrow::Cow;

#[derive(Clone)]
pub enum Expr<'a, C: Column> {
    Equal(C, Value),
    Gt(C, Value),
    Lt(C, Value),
    Like(C, Value),
    In(C, Vec<Value>),
    Raw(Cow<'a, str>),
    And(Box<Expr<'a, C>>, Box<Expr<'a, C>>),
    Or(Box<Expr<'a, C>>, Box<Expr<'a, C>>),
}

impl<'a, C: Column> Expr<'a, C> {
    pub fn and(self, other: Expr<'a, C>) -> Expr<'a, C> {
        Expr::And(Box::new(self), Box::new(other))
    }

    pub fn or(self, other: Expr<'a, C>) -> Expr<'a, C> {
        Expr::Or(Box::new(self), Box::new(other))
    }

    pub fn both(left: Expr<'a, C>, right: Expr<'a, C>) -> Expr<'a, C> {
        Expr::And(Box::new(left), Box::new(right))
    }

    pub fn either(left: Expr<'a, C>, right: Expr<'a, C>) -> Expr<'a, C> {
        Expr::Or(Box::new(left), Box::new(right))
    }

    pub(crate) fn write(self, f: &mut String, values: &mut Vec<Value>) {
        match self {
            Expr::Equal(column, value) => {
                column.write(f);
                match value {
                    Value::Null => f.push_str(" IS NULL"),
                    _ => {
                        f.push_str(" = ?");
                        values.push(value);
                    }
                }
            }
            Expr::Gt(column, value) => {
                column.write(f);
                f.push_str(" > ?");
                values.push(value);
            }
            Expr::Lt(column, value) => {
                column.write(f);
                f.push_str(" < ?");
                values.push(value);
            }
            Expr::And(left, right) => {
                f.push_str("(");
                left.write(f, values);
                f.push_str(") AND (");
                right.write(f, values);
                f.push_str(")");
            }
            Expr::Or(left, right) => {
                f.push_str("(");
                left.write(f, values);
                f.push_str(") OR (");
                right.write(f, values);
                f.push_str(")");
            }
            Expr::Raw(raw) => {
                f.push_str(&raw);
            }
            Expr::Like(column, value) => {
                column.write(f);
                f.push_str(" LIKE ?");
                values.push(value);
            }
            Expr::In(column, values_list) => {
                column.write(f);
                f.push_str(" IN (");
                let mut first = true;
                for value in values_list {
                    if !first {
                        f.push_str(", ");
                    } else {
                        first = false;
                    }
                    f.push('?');
                    values.push(value);
                }
                f.push(')');
            }
        }
    }
}