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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
use chrono::{NaiveDate, NaiveDateTime, NaiveTime};
use r2d2_mysql::mysql::consts::{ColumnFlags, ColumnType};
use rust_decimal::Decimal;
use serde_json::Value;

#[derive(Copy, Clone, Debug)]
pub enum MySQLTypeSystem {
    Float(bool),
    Double(bool),
    Tiny(bool),
    Short(bool),
    Long(bool),
    Int24(bool),
    LongLong(bool),
    UTiny(bool),
    UShort(bool),
    ULong(bool),
    UInt24(bool),
    ULongLong(bool),
    Datetime(bool),
    Date(bool),
    Time(bool),
    Decimal(bool),
    Char(bool),
    VarChar(bool),
    Timestamp(bool),
    Year(bool),
    Enum(bool),
    TinyBlob(bool),
    Blob(bool),
    MediumBlob(bool),
    LongBlob(bool),
    Json(bool),
}

impl_typesystem! {
    system = MySQLTypeSystem,
    mappings = {
        { Tiny => i8 }
        { Short | Year => i16 }
        { Long | Int24 => i32}
        { LongLong => i64 }
        { Float => f32 }
        { Double => f64 }
        { UTiny => u8 }
        { UShort => u16 }
        { ULong | UInt24 => u32}
        { ULongLong => u64 }
        { Datetime | Timestamp => NaiveDateTime }
        { Date => NaiveDate }
        { Time => NaiveTime }
        { Decimal => Decimal }
        { Char | VarChar | Enum => String }
        { TinyBlob | Blob | MediumBlob | LongBlob => Vec<u8>}
        { Json => Value }
    }
}

impl<'a> From<(&'a ColumnType, &'a ColumnFlags)> for MySQLTypeSystem {
    fn from(col: (&'a ColumnType, &'a ColumnFlags)) -> MySQLTypeSystem {
        use MySQLTypeSystem::*;
        let (ty, flag) = col;
        let null_ok = !flag.contains(ColumnFlags::NOT_NULL_FLAG);
        let unsigned = flag.contains(ColumnFlags::UNSIGNED_FLAG);
        match ty {
            ColumnType::MYSQL_TYPE_TINY => {
                if unsigned {
                    UTiny(null_ok)
                } else {
                    Tiny(null_ok)
                }
            }
            ColumnType::MYSQL_TYPE_SHORT => {
                if unsigned {
                    UShort(null_ok)
                } else {
                    Short(null_ok)
                }
            }
            ColumnType::MYSQL_TYPE_INT24 => {
                if unsigned {
                    UInt24(null_ok)
                } else {
                    Int24(null_ok)
                }
            }
            ColumnType::MYSQL_TYPE_LONG => {
                if unsigned {
                    ULong(null_ok)
                } else {
                    Long(null_ok)
                }
            }
            ColumnType::MYSQL_TYPE_LONGLONG => {
                if unsigned {
                    ULongLong(null_ok)
                } else {
                    LongLong(null_ok)
                }
            }
            ColumnType::MYSQL_TYPE_FLOAT => Float(null_ok),
            ColumnType::MYSQL_TYPE_DOUBLE => Double(null_ok),
            ColumnType::MYSQL_TYPE_DATETIME => Datetime(null_ok),
            ColumnType::MYSQL_TYPE_DATE => Date(null_ok),
            ColumnType::MYSQL_TYPE_TIME => Time(null_ok),
            ColumnType::MYSQL_TYPE_DECIMAL => Decimal(null_ok),
            ColumnType::MYSQL_TYPE_NEWDECIMAL => Decimal(null_ok),
            ColumnType::MYSQL_TYPE_STRING => Char(null_ok),
            ColumnType::MYSQL_TYPE_VAR_STRING => VarChar(null_ok),
            ColumnType::MYSQL_TYPE_TIMESTAMP => Timestamp(null_ok),
            ColumnType::MYSQL_TYPE_YEAR => Year(null_ok),
            ColumnType::MYSQL_TYPE_ENUM => Enum(null_ok),
            ColumnType::MYSQL_TYPE_TINY_BLOB => TinyBlob(null_ok),
            ColumnType::MYSQL_TYPE_BLOB => Blob(null_ok),
            ColumnType::MYSQL_TYPE_MEDIUM_BLOB => MediumBlob(null_ok),
            ColumnType::MYSQL_TYPE_LONG_BLOB => LongBlob(null_ok),
            ColumnType::MYSQL_TYPE_JSON => Json(null_ok),
            ColumnType::MYSQL_TYPE_VARCHAR => VarChar(null_ok),
            _ => unimplemented!("{}", format!("{:?}", ty)),
        }
    }
}