From 4c8c773c84a48963e892c72f38f37bcb99b6eb74 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Tue, 3 Jan 2017 10:01:16 +0100 Subject: Rename askama_codegen to askama_derive This appears to be best practice for crates using macros 1.1. --- askama_derive/src/generator.rs | 101 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 askama_derive/src/generator.rs (limited to 'askama_derive/src/generator.rs') diff --git a/askama_derive/src/generator.rs b/askama_derive/src/generator.rs new file mode 100644 index 0000000..b1babce --- /dev/null +++ b/askama_derive/src/generator.rs @@ -0,0 +1,101 @@ +use parser::{Expr, Node}; +use std::str; + +struct Generator { + buf: String, + indent: u8, + start: bool, +} + +impl Generator { + + fn new() -> Generator { + Generator { buf: String::new(), indent: 0, start: true } + } + + fn init(&mut self, name: &str) { + self.write("impl askama::Template for "); + self.write(name); + self.writeln(" {"); + self.indent(); + self.writeln("fn render(&self) -> String {"); + self.indent(); + self.writeln("let mut buf = String::new();"); + } + + fn indent(&mut self) { + self.indent += 1; + } + + fn dedent(&mut self) { + self.indent -= 1; + } + + fn write(&mut self, s: &str) { + if self.start { + for _ in 0..(self.indent * 4) { + self.buf.push(' '); + } + self.start = false; + } + self.buf.push_str(s); + } + + fn writeln(&mut self, s: &str) { + if s.is_empty() { + return; + } + self.write(s); + self.buf.push('\n'); + self.start = true; + } + + fn visit_lit(&mut self, s: &[u8]) { + self.write("buf.push_str("); + self.write(&format!("{:#?}", str::from_utf8(s).unwrap())); + self.writeln(");"); + } + + fn visit_var(&mut self, s: &[u8]) { + let var_name = str::from_utf8(s).unwrap(); + let code = format!("std::fmt::Write::write_fmt(\ + &mut buf, format_args!(\"{{}}\", self.{})).unwrap();", var_name); + self.writeln(&code); + } + + fn visit_expr(&mut self, expr: &Expr) { + match expr { + &Expr::Var(s) => self.visit_var(s), + } + } + + fn handle(&mut self, tokens: &Vec) { + for n in tokens { + match n { + &Node::Lit(val) => { self.visit_lit(val); }, + &Node::Expr(ref val) => { self.visit_expr(&val); }, + } + } + } + + fn finalize(&mut self) { + self.writeln("buf"); + self.dedent(); + self.writeln("}"); + self.dedent(); + self.writeln("}"); + } + + fn result(self) -> String { + self.buf + } + +} + +pub fn generate(ctx_name: &str, tokens: &Vec) -> String { + let mut gen = Generator::new(); + gen.init(ctx_name); + gen.handle(tokens); + gen.finalize(); + gen.result() +} -- cgit