aboutsummaryrefslogtreecommitdiffstats
path: root/askama_derive
diff options
context:
space:
mode:
authorLibravatar Dirkjan Ochtman <dirkjan@ochtman.nl>2017-01-07 20:33:29 +0100
committerLibravatar Dirkjan Ochtman <dirkjan@ochtman.nl>2017-01-07 20:33:29 +0100
commit5d193ce822fab739f889a70c1defa402ddea8eab (patch)
treed9ec0d8998ca9850d879809e66f8037bd3beed1e /askama_derive
parent9837efad983dd0de6439a8c9d59165df01adfe3f (diff)
downloadaskama-5d193ce822fab739f889a70c1defa402ddea8eab.tar.gz
askama-5d193ce822fab739f889a70c1defa402ddea8eab.tar.bz2
askama-5d193ce822fab739f889a70c1defa402ddea8eab.zip
Move parser and generator code into askama crate
Diffstat (limited to 'askama_derive')
-rw-r--r--askama_derive/Cargo.toml2
-rw-r--r--askama_derive/src/generator.rs111
-rw-r--r--askama_derive/src/lib.rs10
-rw-r--r--askama_derive/src/parser.rs69
4 files changed, 4 insertions, 188 deletions
diff --git a/askama_derive/Cargo.toml b/askama_derive/Cargo.toml
index e9bfa66..400cbd3 100644
--- a/askama_derive/Cargo.toml
+++ b/askama_derive/Cargo.toml
@@ -7,5 +7,5 @@ authors = ["Dirkjan Ochtman <dirkjan@ochtman.nl>"]
proc-macro = true
[dependencies]
+askama = { path = "../askama" }
syn = "0.10"
-nom = "2.0"
diff --git a/askama_derive/src/generator.rs b/askama_derive/src/generator.rs
deleted file mode 100644
index 0e80265..0000000
--- a/askama_derive/src/generator.rs
+++ /dev/null
@@ -1,111 +0,0 @@
-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_var(&mut self, s: &[u8]) {
- self.write(&format!("self.{}", str::from_utf8(s).unwrap()));
- }
-
- fn visit_filter(&mut self, name: &str, val: &Expr) {
- self.write(&format!("askama::filters::{}(&", name));
- self.visit_expr(val);
- self.write(")");
- }
-
- fn visit_expr(&mut self, expr: &Expr) {
- match expr {
- &Expr::Var(s) => self.visit_var(s),
- &Expr::Filter(name, ref val) => self.visit_filter(name, &val),
- }
- }
-
- fn write_lit(&mut self, s: &[u8]) {
- self.write("buf.push_str(");
- self.write(&format!("{:#?}", str::from_utf8(s).unwrap()));
- self.writeln(");");
- }
-
- fn write_expr(&mut self, s: &Expr) {
- self.write("std::fmt::Write::write_fmt(&mut buf, format_args!(\"{}\", ");
- self.visit_expr(s);
- self.writeln(")).unwrap();");
- }
-
- fn handle(&mut self, tokens: &Vec<Node>) {
- for n in tokens {
- match n {
- &Node::Lit(val) => { self.write_lit(val); },
- &Node::Expr(ref val) => { self.write_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<Node>) -> String {
- let mut gen = Generator::new();
- gen.init(ctx_name);
- gen.handle(tokens);
- gen.finalize();
- gen.result()
-}
diff --git a/askama_derive/src/lib.rs b/askama_derive/src/lib.rs
index 3b8fe55..8613ead 100644
--- a/askama_derive/src/lib.rs
+++ b/askama_derive/src/lib.rs
@@ -1,13 +1,9 @@
#![feature(proc_macro, proc_macro_lib)]
-#[macro_use]
-extern crate nom;
+extern crate askama;
extern crate proc_macro;
extern crate syn;
-mod generator;
-mod parser;
-
use proc_macro::TokenStream;
use std::fs::File;
use std::io::Read;
@@ -65,6 +61,6 @@ pub fn derive_template(input: TokenStream) -> TokenStream {
let name = &ast.ident;
let path = get_path_from_attrs(&ast.attrs);
let src = get_template_source(&path);
- let tokens = parser::parse(&src);
- generator::generate(name.as_ref(), &tokens).parse().unwrap()
+ let tokens = askama::parser::parse(&src);
+ askama::generator::generate(name.as_ref(), &tokens).parse().unwrap()
}
diff --git a/askama_derive/src/parser.rs b/askama_derive/src/parser.rs
deleted file mode 100644
index cd93971..0000000
--- a/askama_derive/src/parser.rs
+++ /dev/null
@@ -1,69 +0,0 @@
-use nom::{self, IResult};
-use std::str;
-
-pub enum Expr<'a> {
- Var(&'a [u8]),
- Filter(&'a str, Box<Expr<'a>>),
-}
-
-pub enum Node<'a> {
- Lit(&'a [u8]),
- Expr(Expr<'a>),
-}
-
-fn take_content(i: &[u8]) -> IResult<&[u8], Node> {
- if i.len() < 1 || i[0] == b'{' {
- return IResult::Error(error_position!(nom::ErrorKind::TakeUntil, i));
- }
- for (j, c) in i.iter().enumerate() {
- if *c == b'{' {
- if i.len() < j + 2 {
- return IResult::Done(&i[..0], Node::Lit(&i[..]));
- } else if i[j + 1] == '{' as u8 {
- return IResult::Done(&i[j..], Node::Lit(&i[..j]));
- } else if i[j + 1] == '%' as u8 {
- return IResult::Done(&i[j..], Node::Lit(&i[..j]));
- }
- }
- }
- IResult::Done(&i[..0], Node::Lit(&i[..]))
-}
-
-named!(expr_var<Expr>, map!(nom::alphanumeric, Expr::Var));
-
-fn expr_filtered(i: &[u8]) -> IResult<&[u8], Expr> {
- let (mut left, mut expr) = match expr_var(i) {
- IResult::Error(err) => { return IResult::Error(err); },
- IResult::Incomplete(needed) => { return IResult::Incomplete(needed); },
- IResult::Done(left, res) => (left, res),
- };
- while left[0] == b'|' {
- match nom::alphanumeric(&left[1..]) {
- IResult::Error(err) => {
- return IResult::Error(err);
- },
- IResult::Incomplete(needed) => {
- return IResult::Incomplete(needed);
- },
- IResult::Done(new_left, res) => {
- left = new_left;
- expr = Expr::Filter(str::from_utf8(res).unwrap(), Box::new(expr));
- },
- };
- }
- return IResult::Done(left, expr);
-}
-
-named!(expr_node<Node>, map!(
- delimited!(tag_s!("{{"), ws!(expr_filtered), tag_s!("}}")),
- Node::Expr));
-
-named!(parse_template< Vec<Node> >, many1!(alt!(take_content | expr_node)));
-
-pub fn parse<'a>(src: &'a str) -> Vec<Node> {
- match parse_template(src.as_bytes()) {
- IResult::Done(_, res) => res,
- IResult::Error(err) => panic!("problems parsing template source: {}", err),
- IResult::Incomplete(_) => panic!("parsing incomplete"),
- }
-}