1 use sql_types::{self, NotNull};
2 
3 /// Represents SQL types which can be used with `SUM` and `AVG`
4 pub trait Foldable {
5     /// The SQL type of `sum(this_type)`
6     type Sum;
7     /// The SQL type of `avg(this_type)`
8     type Avg;
9 }
10 
11 impl<T> Foldable for sql_types::Nullable<T>
12 where
13     T: Foldable + NotNull,
14 {
15     type Sum = T::Sum;
16     type Avg = T::Avg;
17 }
18 
19 macro_rules! foldable_impls {
20     ($($Source:ty => ($SumType:ty, $AvgType:ty)),+,) => {
21         $(
22             impl Foldable for $Source {
23                 type Sum = sql_types::Nullable<$SumType>;
24                 type Avg = sql_types::Nullable<$AvgType>;
25             }
26         )+
27     }
28 }
29 
30 foldable_impls! {
31     sql_types::SmallInt => (sql_types::BigInt, sql_types::Numeric),
32     sql_types::Integer => (sql_types::BigInt, sql_types::Numeric),
33     sql_types::BigInt => (sql_types::Numeric, sql_types::Numeric),
34 
35     sql_types::Float => (sql_types::Float, sql_types::Double),
36     sql_types::Double => (sql_types::Double, sql_types::Double),
37     sql_types::Numeric => (sql_types::Numeric, sql_types::Numeric),
38 
39     sql_types::Interval => (sql_types::Interval, sql_types::Interval),
40 }
41 
42 #[cfg(feature = "mysql")]
43 foldable_impls! {
44     sql_types::Unsigned<sql_types::SmallInt> => (sql_types::Unsigned<sql_types::BigInt>, sql_types::Numeric),
45     sql_types::Unsigned<sql_types::Integer> => (sql_types::Unsigned<sql_types::BigInt>, sql_types::Numeric),
46     sql_types::Unsigned<sql_types::BigInt> => (sql_types::Numeric, sql_types::Numeric),
47 }
48