gorm 0.1.4

An orm that is simple to use and prevents all mistakes at compile time
Documentation
use std::{fmt::Write, marker::PhantomData};

use crate::sql::{
    ParameterBinder, SelectableTables, SqlAdd, SqlDivide, SqlExpression, SqlMultiply, SqlSubtract,
};

macro_rules! define_operator{
    {$type_name: ident, $sql_type_marker: ident, $operator: tt} => {
        pub struct $type_name<S: SelectableTables, Lhs: SqlExpression<S>, Rhs: SqlExpression<S>>
        where
            Lhs::SqlType: $sql_type_marker<Rhs::SqlType>
        {
            lhs: Lhs,
            rhs: Rhs,
            phantom: PhantomData<S>,
        }

        impl<S: SelectableTables, Lhs: SqlExpression<S>, Rhs: SqlExpression<S>>
            $type_name<S, Lhs, Rhs>
        where
            Lhs::SqlType: $sql_type_marker<Rhs::SqlType>
        {
            pub fn new(lhs: Lhs, rhs: Rhs) -> Self {
                Self {
                    lhs,
                    rhs,
                    phantom: PhantomData,
                }
            }
        }

        impl<S: SelectableTables, Lhs: SqlExpression<S>, Rhs: SqlExpression<S>> SqlExpression<S>
            for $type_name<S, Lhs, Rhs>
        where
            Lhs::SqlType: $sql_type_marker<Rhs::SqlType>
        {
            type SqlType = Lhs::SqlType;
            type RustType = Lhs::RustType;

            const IS_AGGREGATE:bool = Lhs::IS_AGGREGATE || Rhs::IS_AGGREGATE;

            fn write_sql_string<'s, 'a>(
                &'s self,
                f: &mut String,
                parameter_binder: &mut ParameterBinder<'a>,
            ) -> std::fmt::Result
            where
                's: 'a,
            {
                self.lhs.write_parenthesized_sql_string(f, parameter_binder)?;
                write!(f, stringify!($operator))?;
                self.rhs.write_parenthesized_sql_string(f, parameter_binder)?;
                Ok(())
            }
        }

    }
}

define_operator! {SqlAddition, SqlAdd, +}
define_operator! {SqlSubtraction, SqlSubtract, -}
define_operator! {SqlMultiplication, SqlMultiply, *}
define_operator! {SqlDivision, SqlDivide, /}