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
extern crate redis;
extern crate postgres;
extern crate chrono;
extern crate rustc_serialize;
extern crate bincode;
use chrono::*;
use std::io::prelude::*;
use rustc_serialize::*;
use postgres::types::{Type, FromSql, ToSql, IsNull, SessionInfo};
use redis::{RedisResult, ToRedisArgs, FromRedisValue, RedisError, Value};
use std::io::{Error, ErrorKind};
use bincode::SizeLimit;
use bincode::rustc_serialize::{encode, decode};
use std::ops::Deref;
const FORMAT: &'static str = "%Y-%m-%d %H:%M:%S";
#[derive(Debug,Copy,Clone, PartialEq,Eq)]
pub struct Time {
value: DateTime<Local>,
}
impl Deref for Time {
type Target = DateTime<Local>;
fn deref(&self) -> &DateTime<Local> {
&self.value
}
}
impl Encodable for Time {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
self.value.format(FORMAT).to_string().encode(s)
}
}
impl Decodable for Time {
fn decode<D: Decoder>(d: &mut D) -> Result<Self, D::Error> {
match String::decode(d) {
Ok(value) => {
match Local.datetime_from_str(&value, FORMAT) {
Ok(value) => Ok(Time { value: value }),
Err(_) => panic!("error decode datetime"),
}
}
Err(_) => panic!("error decode datetime"),
}
}
}
impl Time {
pub fn new() -> Self {
Time { value: Local::now() }
}
}
impl FromSql for Time {
fn from_sql<R: Read>(ty: &Type, raw: &mut R, ctx: &SessionInfo) -> postgres::Result<Time> {
DateTime::from_sql(ty, raw, ctx).map(|value| Time { value: value })
}
fn accepts(_: &Type) -> bool {
true
}
}
impl ToSql for Time {
fn to_sql<W: Write + ?Sized>(&self,
ty: &Type,
mut w: &mut W,
ctx: &SessionInfo)
-> postgres::Result<IsNull> {
self.value.to_sql(ty, w, ctx)
}
fn accepts(_: &Type) -> bool {
true
}
fn to_sql_checked(&self,
ty: &Type,
out: &mut Write,
ctx: &SessionInfo)
-> postgres::Result<IsNull> {
self.value.to_sql_checked(ty, out, ctx)
}
}
impl ToRedisArgs for Time {
fn to_redis_args(&self) -> Vec<Vec<u8>> {
vec![encode(&self.value, SizeLimit::Infinite).unwrap()]
}
}
impl FromRedisValue for Time {
fn from_redis_value(v: &Value) -> RedisResult<Self> {
if let Value::Data(ref items) = *v {
let decoded: DateTime<Local> = decode(&items[..]).unwrap();
return Ok(Time { value: decoded });
}
Err(RedisError::from(Error::new(ErrorKind::Other, "oh no!")))
}
}