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
123
124
125
126
127
use time::{at_utc, Tm, Timespec};
use json::{FromJsonnable, ToJsonnable};
use serde::de::{Error, Type};
use serde_json::value::Value;
use serde_json::error::Error as JsonError;
use serde_json::builder::ObjectBuilder;
impl FromJsonnable for Tm {
fn from_json(json: Value) -> Result<Self, JsonError> {
match json {
Value::Object(map) => {
let sec =
match map.get("sec") {
Some(sec) =>
match sec {
&Value::I64(sec) => sec,
&Value::U64(sec) => sec as i64,
_ => return Err(JsonError::invalid_type(Type::I64)),
},
None => return Err(JsonError::missing_field("Missing \"sec\"")),
};
let nsec =
match map.get("nsec") {
Some(nsec) =>
match nsec {
&Value::I64(nsec) => nsec as i32,
&Value::U64(nsec) => nsec as i32,
_ => return Err(JsonError::invalid_type(Type::I32)),
},
None => return Err(JsonError::missing_field("Missing \"nsec\"")),
};
Ok(at_utc(Timespec::new(sec, nsec)))
},
_ => Err(JsonError::invalid_type(Type::Struct)),
}
}
}
impl ToJsonnable for Tm {
fn to_json(&self) -> Value {
let spec = self.to_timespec();
ObjectBuilder::new().insert("sec", &spec.sec)
.insert("nsec", &spec.nsec)
.build()
}
}
impl<T: FromJsonnable> FromJsonnable for Vec<T> {
fn from_json(json: Value) -> Result<Self, JsonError> {
match json {
Value::Array(arr) => {
let mut elems: Vec<T> = Vec::with_capacity(arr.len());
for elem in arr {
match T::from_json(elem) {
Ok(elem) => elems.push(elem),
Err(e) => return Err(e),
}
}
Ok(elems)
},
_ => Err(JsonError::invalid_type(Type::Seq)),
}
}
}
impl<T: ToJsonnable> ToJsonnable for Vec<T> {
fn to_json(&self) -> Value {
Value::Array(self.iter().map(|ref elem| elem.to_json()).collect())
}
}
macro_rules! primitive_to_json {
($t:ty, $v:ident, $d:ty) => {
impl ToJsonnable for $t {
fn to_json(&self) -> Value {
Value::$v(self.clone() as $d)
}
}
};
}
macro_rules! primitive_from_json {
($t:ty, $expected:ident, $($v:ident)+) => {
impl FromJsonnable for $t {
fn from_json(json: Value) -> Result<Self, JsonError> {
match json {
$(
Value::$v(value) => Ok(value as $t),
)+
_ => Err(JsonError::invalid_type(Type::$expected)),
}
}
}
};
}
primitive_to_json!(i8, I64, i64);
primitive_to_json!(i16, I64, i64);
primitive_to_json!(i32, I64, i64);
primitive_to_json!(i64, I64, i64);
primitive_to_json!(u8, U64, u64);
primitive_to_json!(u16, U64, u64);
primitive_to_json!(u32, U64, u64);
primitive_to_json!(u64, U64, u64);
primitive_to_json!(f32, F64, f64);
primitive_to_json!(f64, F64, f64);
primitive_from_json!(i8, I64, I64 U64);
primitive_from_json!(i16, I64, I64 U64);
primitive_from_json!(i32, I64, I64 U64);
primitive_from_json!(i64, I64, I64 U64);
primitive_from_json!(u8, U64, U64);
primitive_from_json!(u16, U64, U64);
primitive_from_json!(u32, U64, U64);
primitive_from_json!(u64, U64, U64);
primitive_from_json!(f32, F64, F64);
primitive_from_json!(f64, F64, F64);