1 #[macro_export]
2 /// Implements the Rust operator for a given type. If you create a new SQL
3 /// function, which returns a type that you'd like to use an operator on, you
4 /// should invoke this macro. Unfortunately, Rust disallows us from
5 /// automatically implementing `Add` and other traits from `std::ops`, under its
6 /// orphan rules.
7 macro_rules! operator_allowed {
8     ($tpe:ty, $op:ident, $fn_name:ident) => {
9         impl<Rhs> ::std::ops::$op<Rhs> for $tpe
10         where
11             Rhs: $crate::expression::AsExpression<
12                 <<$tpe as $crate::Expression>::SqlType as $crate::sql_types::ops::$op>::Rhs,
13             >,
14         {
15             type Output = $crate::expression::ops::$op<Self, Rhs::Expression>;
16 
17             fn $fn_name(self, rhs: Rhs) -> Self::Output {
18                 $crate::expression::ops::$op::new(self, rhs.as_expression())
19             }
20         }
21     };
22 }
23 
24 #[macro_export]
25 /// Indicates that an expression allows all numeric operators. If you create new
26 /// SQL functions that return a numeric type, you should invoke this macro that
27 /// type. Unfortunately, Rust disallows us from automatically implementing `Add`
28 /// for types which implement `Expression`, under its orphan rules.
29 macro_rules! numeric_expr {
30     ($tpe:ty) => {
31         operator_allowed!($tpe, Add, add);
32         operator_allowed!($tpe, Sub, sub);
33         operator_allowed!($tpe, Div, div);
34         operator_allowed!($tpe, Mul, mul);
35     };
36 }
37 
38 #[macro_export]
39 #[doc(hidden)]
40 macro_rules! __diesel_generate_ops_impls_if_numeric {
41     ($column_name:ident, Nullable<$($inner:tt)::*>) => { __diesel_generate_ops_impls_if_numeric!($column_name, $($inner)::*); };
42 
43     ($column_name:ident, SmallInt) => { numeric_expr!($column_name); };
44     ($column_name:ident, Int2) => { numeric_expr!($column_name); };
45     ($column_name:ident, Smallint) => { numeric_expr!($column_name); };
46     ($column_name:ident, SmallSerial) => { numeric_expr!($column_name); };
47 
48     ($column_name:ident, Integer) => { numeric_expr!($column_name); };
49     ($column_name:ident, Int4) => { numeric_expr!($column_name); };
50     ($column_name:ident, Serial) => { numeric_expr!($column_name); };
51 
52     ($column_name:ident, BigInt) => { numeric_expr!($column_name); };
53     ($column_name:ident, Int8) => { numeric_expr!($column_name); };
54     ($column_name:ident, Bigint) => { numeric_expr!($column_name); };
55     ($column_name:ident, BigSerial) => { numeric_expr!($column_name); };
56 
57     ($column_name:ident, Float) => { numeric_expr!($column_name); };
58     ($column_name:ident, Float4) => { numeric_expr!($column_name); };
59 
60     ($column_name:ident, Double) => { numeric_expr!($column_name); };
61     ($column_name:ident, Float8) => { numeric_expr!($column_name); };
62 
63     ($column_name:ident, Numeric) => { numeric_expr!($column_name); };
64 
65     ($column_name:ident, $non_numeric_type:ty) => {};
66 }
67 
68 #[macro_export]
69 #[doc(hidden)]
70 macro_rules! date_time_expr {
71     ($tpe:ty) => {
72         operator_allowed!($tpe, Add, add);
73         operator_allowed!($tpe, Sub, sub);
74     };
75 }
76 
77 #[macro_export]
78 #[doc(hidden)]
79 macro_rules! __diesel_generate_ops_impls_if_date_time {
80     ($column_name:ident, Nullable<$($inner:tt)::*>) => { __diesel_generate_ops_impls_if_date_time!($column_name, $($inner)::*); };
81     ($column_name:ident, Time) => { date_time_expr!($column_name); };
82     ($column_name:ident, Date) => { date_time_expr!($column_name); };
83     ($column_name:ident, Timestamp) => { date_time_expr!($column_name); };
84     ($column_name:ident, Timestamptz) => { date_time_expr!($column_name); };
85     ($column_name:ident, $non_date_time_type:ty) => {};
86 }
87