use std::collections::HashMap;
use uuid::Uuid;
use chrono::datetime::DateTime;
use chrono::naive::date::NaiveDate;
use chrono::naive::time::NaiveTime;
use chrono::naive::datetime::NaiveDateTime;
use chrono::offset::utc::UTC;
#[derive(RustcDecodable, RustcEncodable)]
#[derive(Debug)]
#[derive(Clone)]
pub enum Type{
Bool(bool),
I8(i8),
I16(i16),
I32(i32),
I64(i64),
U8(u8),
U16(u16),
U32(u32),
U64(u64),
F32(f32),
F64(f64),
String(String),
VecU8(Vec<u8>),
Map(HashMap<String, Option<String>>),
Uuid(Uuid),
DateTime(DateTime<UTC>),
NaiveDate(NaiveDate),
NaiveTime(NaiveTime),
NaiveDateTime(NaiveDateTime),
}
pub trait ToType{
fn to_db_type(&self)->Type;
}
impl ToType for i8{
fn to_db_type(&self)->Type{
Type::I8(self.clone())
}
}
impl ToType for i16{
fn to_db_type(&self)->Type{
Type::I16(self.clone())
}
}
impl ToType for i32{
fn to_db_type(&self)->Type{
Type::I32(self.clone())
}
}
impl ToType for i64{
fn to_db_type(&self)->Type{
Type::I64(self.clone())
}
}
impl ToType for u8{
fn to_db_type(&self)->Type{
Type::U8(self.clone())
}
}
impl ToType for u16{
fn to_db_type(&self)->Type{
Type::U16(self.clone())
}
}
impl ToType for u32{
fn to_db_type(&self)->Type{
Type::U32(self.clone())
}
}
impl ToType for u64{
fn to_db_type(&self)->Type{
Type::U64(self.clone())
}
}
impl <'a>ToType for &'a str{
fn to_db_type(&self)->Type{
Type::String(self.to_string())
}
}
impl ToType for String{
fn to_db_type(&self)->Type{
Type::String(self.clone())
}
}
impl ToType for Uuid{
fn to_db_type(&self)->Type{
Type::Uuid(self.clone())
}
}
impl ToType for DateTime<UTC>{
fn to_db_type(&self)->Type{
Type::DateTime(self.clone())
}
}
impl ToType for NaiveDate{
fn to_db_type(&self)->Type{
Type::NaiveDate(self.clone())
}
}
impl ToType for NaiveTime{
fn to_db_type(&self)->Type{
Type::NaiveTime(self.clone())
}
}
impl ToType for NaiveDateTime{
fn to_db_type(&self)->Type{
Type::NaiveDateTime(self.clone())
}
}
pub trait FromType: Sized{
fn from_type(ty:Type)->Self;
}
impl FromType for i8{
fn from_type(ty:Type)->Self{
match ty{
Type::I8(x) => x,
_ => panic!("error!"),
}
}
}
impl FromType for i16{
fn from_type(ty:Type)->Self{
match ty{
Type::I16(x) => x,
_ => panic!("error!"),
}
}
}
impl FromType for i32{
fn from_type(ty:Type)->Self{
match ty{
Type::I32(x) => x,
_ => panic!("error!"),
}
}
}
impl FromType for i64{
fn from_type(ty:Type)->Self{
match ty{
Type::I64(x) => x,
_ => panic!("error!"),
}
}
}
impl FromType for u8{
fn from_type(ty:Type)->Self{
match ty{
Type::U8(x) => x,
_ => panic!("error!"),
}
}
}
impl FromType for u16{
fn from_type(ty:Type)->Self{
match ty{
Type::U16(x) => x,
_ => panic!("error!"),
}
}
}
impl FromType for u32{
fn from_type(ty:Type)->Self{
match ty{
Type::U32(x) => x,
_ => panic!("error!"),
}
}
}
impl FromType for u64{
fn from_type(ty:Type)->Self{
match ty{
Type::U64(x) => x,
_ => panic!("error!"),
}
}
}
impl FromType for f32{
fn from_type(ty:Type)->Self{
match ty{
Type::F32(x) => x,
_ => panic!("error!"),
}
}
}
impl FromType for f64{
fn from_type(ty:Type)->Self{
match ty{
Type::F64(x) => x,
_ => panic!("error!"),
}
}
}
impl FromType for String{
fn from_type(ty:Type)->Self{
match ty{
Type::String(x) => x,
_ => panic!("error!"),
}
}
}
impl FromType for DateTime<UTC>{
fn from_type(ty:Type)->Self{
match ty{
Type::DateTime(x) => x,
_ => panic!("error!"),
}
}
}
impl FromType for NaiveTime{
fn from_type(ty:Type)->Self{
match ty{
Type::NaiveTime(x) => x,
_ => panic!("error!"),
}
}
}
impl FromType for NaiveDate{
fn from_type(ty:Type)->Self{
match ty{
Type::NaiveDate(x) => x,
_ => panic!("error!"),
}
}
}
impl FromType for NaiveDateTime{
fn from_type(ty:Type)->Self{
match ty{
Type::NaiveDateTime(x) => x,
_ => panic!("error!"),
}
}
}
#[derive(RustcDecodable, RustcEncodable)]
pub struct Dao{
pub values:HashMap<String, Type>
}
impl Dao{
pub fn new()->Self{
Dao{values:HashMap::new()}
}
pub fn set_value(&mut self, column: &str, value:&ToType){
self.values.insert(column.to_string(), value.to_db_type());
}
pub fn remove<T>(&mut self, column: &str) -> T where T: FromType{
let value = self.values.remove(column).unwrap();
FromType::from_type(value)
}
pub fn get<T>(&mut self, column: &str) -> T where T: FromType{
let value = self.values.get(column).unwrap();
FromType::from_type(value.clone())
}
pub fn get_opt<T>(&mut self, column: &str) -> Option<T> where T: FromType{
let value = self.values.get(column);
if value.is_some(){
Some(FromType::from_type(value.unwrap().clone()))
}else{
None
}
}
pub fn get_ref(&self, column: &str)->&Type{
self.values.get(column).unwrap()
}
}
#[test]
fn test_dao(){
let s = "lee";
let n = 20i8;
let date = UTC::now();
let mut d = Dao::new();
d.set_value("name", &s);
d.set_value("age", &n);
d.set_value("created", &date);
let name:String = d.get("name");
let age:i8 = d.get("age");
let created:DateTime<UTC> = d.get("created");
let none:Option<u8> = d.get_opt("none");
assert_eq!(name, s);
assert_eq!(age, 20i8);
assert_eq!(date, created);
assert_eq!(none, None);
}