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