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
use std::fmt::Display;
use std::borrow::Cow;
use std::any::Any;
use rustc_serialize::json::{self, Json};
use rustc_serialize::{Decodable, Encodable};
use result::Result;
pub type RawValue = Json;
pub trait Field: Display + Any + FieldClone {
fn key() -> &'static str where Self: Sized;
fn decode(raw: &RawValue) -> Result<Self> where Self: Sized;
fn encode(&self) -> RawValue;
}
#[doc(hidden)]
pub trait FieldClone {
fn clone_box(&self) -> Box<Field>;
}
impl<T: Field + Clone> FieldClone for T {
#[inline]
fn clone_box(&self) -> Box<Field> { Box::new(self.clone()) }
}
#[inline]
pub fn decode<T: Decodable>(raw: &RawValue) -> Result<T>
where T: Sized
{
let s = raw.to_string();
let t = try!(json::decode(&s));
Ok(t)
}
#[inline]
pub fn encode<T: Encodable>(x: &T) -> RawValue {
let s = json::encode(x).unwrap_or("".to_string());
return Json::from_str(&s).unwrap_or(Json::Null);
}
pub trait FieldRef {
fn get<V>(&self) -> Option<&V> where V: Field;
fn get_raw(&self, name: &str) -> Option<RawValue>;
}
pub trait FieldMut {
fn set<V: Field>(&mut self, value: V);
fn set_raw<K>(&mut self, name: K, value: RawValue) where K: Into<Cow<'static, str>>;
}
impl<'a, T: FieldRef + ?Sized> FieldRef for &'a T {
fn get<V: Field>(&self) -> Option<&V> { FieldRef::get::<V>(*self) }
fn get_raw(&self, name: &str) -> Option<RawValue> { FieldRef::get_raw(*self, name) }
}
impl<'a, T: FieldRef + ?Sized> FieldRef for &'a mut T {
fn get<V: Field>(&self) -> Option<&V> { FieldRef::get::<V>(*self) }
fn get_raw(&self, name: &str) -> Option<RawValue> { FieldRef::get_raw(*self, name) }
}
impl<'a, T: FieldMut + ?Sized> FieldMut for &'a mut T {
fn set<V: Field>(&mut self, value: V) { FieldMut::set(*self, value) }
fn set_raw<K>(&mut self, name: K, value: RawValue)
where K: Into<Cow<'static, str>>
{
FieldMut::set_raw(*self, name, value)
}
}