1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
use types::{self, NotNull};

pub trait Foldable {
    type Sum;
    type Avg;
}

impl<T> Foldable for types::Nullable<T> where
    T: Foldable + NotNull,
    T::Sum: NotNull,
    T::Avg: NotNull,
{
    type Sum = types::Nullable<T::Sum>;
    type Avg = types::Nullable<T::Avg>;
}

macro_rules! foldable_impls {
    ($($Source:ty => ($SumType:ty, $AvgType:ty)),+,) => {
        $(
            impl Foldable for $Source {
                type Sum = $SumType;
                type Avg = $AvgType;
            }
        )+
    }
}

foldable_impls! {
    types::SmallInt => (types::BigInt, types::Numeric),
    types::Integer => (types::BigInt, types::Numeric),
    types::BigInt => (types::Numeric, types::Numeric),

    types::Float => (types::Float, types::Double),
    types::Double => (types::Double, types::Double),
    types::Numeric => (types::Numeric, types::Numeric),

    types::Interval => (types::Interval, types::Interval),
}