1use std::io::Write;
2use compiler;
3use parser;
4use rustc_serialize::json::Json;
5use rustc_serialize::json::Json::{Boolean, Null, I64, U64, F64, Array, Object};
6use rustc_serialize::json::Json::String as JString;
7use build::{HashBuilder, VecBuilder};
8use template::Template;
9use errors::*;
10
11pub trait Render {
13 fn render<W: Write>(&self, template: &str, writer: &mut W) -> Result<()>;
15}
16
17impl<'a> Render for HashBuilder<'a> {
19 fn render<W: Write>(&self, template: &str, writer: &mut W) -> Result<()> {
20 let tokens = compiler::create_tokens(template);
22 let nodes = parser::parse_nodes(&tokens);
23
24 Template::new().render_data(writer, self, &nodes)
26 }
27}
28
29
30impl Render for Json {
32 fn render<W: Write>(&self, template: &str, writer: &mut W) -> Result<()> {
33 parse_json(self).render(template, writer)
34 }
35}
36
37impl Render for ToString {
38 fn render<W: Write>(&self, template: &str, writer: &mut W) -> Result<()> {
39
40 let json = match Json::from_str(&self.to_string()) {
41 Ok(json) => json,
42 Err(err) => return Err(err.into()),
43 };
44
45 parse_json(&json).render(template, writer)
46 }
47}
48
49fn parse_json(json: &Json) -> HashBuilder {
52 let mut data = HashBuilder::new();
53 for (k, v) in json.as_object().unwrap().iter() {
54 match *v {
55 I64(num) => {
56 data = data.insert(&k[..], num.to_string());
57 }
58 U64(num) => {
59 data = data.insert(&k[..], num.to_string());
60 }
61 F64(num) => {
62 data = data.insert(&k[..], num.to_string());
63 }
64 Boolean(val) => {
65 data = data.insert(&k[..], val);
66 }
67 Array(ref list) => {
68 let mut builder = VecBuilder::new();
69 for item in list.iter() {
70 builder = match *item {
71 Object(_) => builder.push(parse_json(item)),
72 Array(_) => builder.push(parse_json_vector(item)),
73 JString(_) => builder.push(item.as_string().unwrap()),
74 Boolean(_) => builder.push(item.as_boolean().unwrap()),
75 _ => builder,
76 }
77 }
78 data = data.insert(&k[..], builder);
79 }
80 Object(_) => {
81 data = data.insert(&k[..], parse_json(v));
82 }
83 Null => {}
84 JString(ref text) => {
85 data = data.insert(&k[..], &text[..]);
86 }
87 }
88 }
89
90 data
91}
92
93fn parse_json_vector(json: &Json) -> VecBuilder {
96 let mut data = VecBuilder::new();
97 for v in json.as_array().unwrap().iter() {
98 match *v {
99 I64(num) => {
100 data = data.push(num.to_string());
101 }
102 U64(num) => {
103 data = data.push(num.to_string());
104 }
105 F64(num) => {
106 data = data.push(num.to_string());
107 }
108 Boolean(val) => {
109 data = data.push(val);
110 }
111 Array(ref list) => {
112 let mut builder = VecBuilder::new();
113 for item in list.iter() {
114 builder = match *item {
115 Object(_) => builder.push(parse_json(item)),
116 Array(_) => builder.push(parse_json_vector(item)),
117 JString(_) => builder.push(item.as_string().unwrap()),
118 Boolean(_) => builder.push(item.as_boolean().unwrap()),
119 _ => builder,
120 }
121 }
122 data = data.push(builder);
123 }
124 Object(_) => {
125 data = data.push(parse_json(v));
126 }
127 Null => {}
128 JString(ref text) => {
129 data = data.push(&text[..]);
130 }
131 }
132 }
133 data
134}