drizzle_core/expr/
ops.rs

1//! Arithmetic operations using std::ops traits.
2//!
3//! This module implements `Add`, `Sub`, `Mul`, `Div`, `Rem` for `SQLExpr`,
4//! enabling natural Rust syntax for SQL arithmetic.
5
6use core::ops::{Add, Div, Mul, Neg, Rem, Sub};
7
8use crate::sql::{SQL, Token};
9use crate::traits::{SQLParam, ToSQL};
10use crate::types::{ArithmeticOutput, Numeric};
11
12use super::{AggregateKind, Expr, NullOr, Nullability, SQLExpr, Scalar};
13
14// =============================================================================
15// Addition
16// =============================================================================
17
18impl<'a, V, T, N, A, Rhs> Add<Rhs> for SQLExpr<'a, V, T, N, A>
19where
20    V: SQLParam + 'a,
21    T: ArithmeticOutput<Rhs::SQLType>,
22    N: Nullability + NullOr<Rhs::Nullable>,
23    A: AggregateKind,
24    Rhs: Expr<'a, V>,
25    Rhs::SQLType: Numeric,
26    Rhs::Nullable: Nullability,
27{
28    type Output = SQLExpr<'a, V, T::Output, <N as NullOr<Rhs::Nullable>>::Output, Scalar>;
29
30    fn add(self, rhs: Rhs) -> Self::Output {
31        SQLExpr::new(self.to_sql().push(Token::PLUS).append(rhs.to_sql()))
32    }
33}
34
35// =============================================================================
36// Subtraction
37// =============================================================================
38
39impl<'a, V, T, N, A, Rhs> Sub<Rhs> for SQLExpr<'a, V, T, N, A>
40where
41    V: SQLParam + 'a,
42    T: ArithmeticOutput<Rhs::SQLType>,
43    N: Nullability + NullOr<Rhs::Nullable>,
44    A: AggregateKind,
45    Rhs: Expr<'a, V>,
46    Rhs::SQLType: Numeric,
47    Rhs::Nullable: Nullability,
48{
49    type Output = SQLExpr<'a, V, T::Output, <N as NullOr<Rhs::Nullable>>::Output, Scalar>;
50
51    fn sub(self, rhs: Rhs) -> Self::Output {
52        SQLExpr::new(self.to_sql().push(Token::MINUS).append(rhs.to_sql()))
53    }
54}
55
56// =============================================================================
57// Multiplication
58// =============================================================================
59
60impl<'a, V, T, N, A, Rhs> Mul<Rhs> for SQLExpr<'a, V, T, N, A>
61where
62    V: SQLParam + 'a,
63    T: ArithmeticOutput<Rhs::SQLType>,
64    N: Nullability + NullOr<Rhs::Nullable>,
65    A: AggregateKind,
66    Rhs: Expr<'a, V>,
67    Rhs::SQLType: Numeric,
68    Rhs::Nullable: Nullability,
69{
70    type Output = SQLExpr<'a, V, T::Output, <N as NullOr<Rhs::Nullable>>::Output, Scalar>;
71
72    fn mul(self, rhs: Rhs) -> Self::Output {
73        SQLExpr::new(self.to_sql().push(Token::STAR).append(rhs.to_sql()))
74    }
75}
76
77// =============================================================================
78// Division
79// =============================================================================
80
81impl<'a, V, T, N, A, Rhs> Div<Rhs> for SQLExpr<'a, V, T, N, A>
82where
83    V: SQLParam + 'a,
84    T: ArithmeticOutput<Rhs::SQLType>,
85    N: Nullability + NullOr<Rhs::Nullable>,
86    A: AggregateKind,
87    Rhs: Expr<'a, V>,
88    Rhs::SQLType: Numeric,
89    Rhs::Nullable: Nullability,
90{
91    type Output = SQLExpr<'a, V, T::Output, <N as NullOr<Rhs::Nullable>>::Output, Scalar>;
92
93    fn div(self, rhs: Rhs) -> Self::Output {
94        SQLExpr::new(self.to_sql().push(Token::SLASH).append(rhs.to_sql()))
95    }
96}
97
98// =============================================================================
99// Remainder (Modulo)
100// =============================================================================
101
102impl<'a, V, T, N, A, Rhs> Rem<Rhs> for SQLExpr<'a, V, T, N, A>
103where
104    V: SQLParam + 'a,
105    T: ArithmeticOutput<Rhs::SQLType>,
106    N: Nullability + NullOr<Rhs::Nullable>,
107    A: AggregateKind,
108    Rhs: Expr<'a, V>,
109    Rhs::SQLType: Numeric,
110    Rhs::Nullable: Nullability,
111{
112    type Output = SQLExpr<'a, V, T::Output, <N as NullOr<Rhs::Nullable>>::Output, Scalar>;
113
114    fn rem(self, rhs: Rhs) -> Self::Output {
115        SQLExpr::new(self.to_sql().push(Token::REM).append(rhs.to_sql()))
116    }
117}
118
119// =============================================================================
120// Negation
121// =============================================================================
122
123impl<'a, V, T, N, A> Neg for SQLExpr<'a, V, T, N, A>
124where
125    V: SQLParam + 'a,
126    T: Numeric,
127    N: Nullability,
128    A: AggregateKind,
129{
130    type Output = SQLExpr<'a, V, T, N, Scalar>;
131
132    fn neg(self) -> Self::Output {
133        SQLExpr::new(SQL::from(Token::MINUS).append(self.to_sql().parens()))
134    }
135}