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
use std::cmp::Eq;
use std::collections::HashMap;
use std::hash::Hash;
use chrono::{DateTime, NaiveDateTime, TimeZone, Utc};
use crate::error::*;
pub struct Row {
pub(crate) body: HashMap<usize, String>,
pub(crate) columns: Vec<String>,
}
impl Row {
pub fn get<T: FromSql, U: RowIndex>(&self, key: U) -> Result<T> {
let column = key.get_index(&self.columns);
let v = self.body.get(&column).unwrap().as_str();
FromSql::from_sql(v)
}
}
pub trait RowIndex: Hash + Eq {
fn get_index(&self, columns: &Vec<String>) -> usize;
}
impl RowIndex for usize {
#[allow(unused_variables)]
fn get_index(&self, columns: &Vec<String>) -> usize {
self.clone()
}
}
impl RowIndex for &str {
fn get_index(&self, columns: &Vec<String>) -> usize {
for (i, v) in columns.iter().enumerate() {
if v == self {
return i
}
}
return 0
}
}
pub trait FromSql: Sized + std::str::FromStr {
fn from_sql(value: &str) -> Result<Self> {
match value.parse() {
Ok(v) => Ok(v),
Err(_) => Err(ErrorKind::ParseError(value.to_owned()).into())
}
}
}
impl FromSql for i8 {}
impl FromSql for i16 {}
impl FromSql for i32 {}
impl FromSql for i64 {}
impl FromSql for u8 {}
impl FromSql for u16 {}
impl FromSql for u32 {}
impl FromSql for u64 {}
impl FromSql for f32 {}
impl FromSql for f64 {}
impl FromSql for String {
fn from_sql(value: &str) -> Result<Self> {
Ok(value.to_owned())
}
}
impl FromSql for bool {
fn from_sql(value: &str) -> Result<Self> {
match value {
"0" => Ok(false),
_ => Ok(true),
}
}
}
impl FromSql for DateTime<Utc> {
fn from_sql(value: &str) -> Result<Self> {
let dt = NaiveDateTime::parse_from_str(value, "%Y-%m-%d %H:%M:%S")?;
let dt: DateTime<Utc> = Utc.from_local_datetime(&dt).unwrap();
Ok(dt)
}
}