aboutsummaryrefslogtreecommitdiffstats
path: root/askama_codegen
diff options
context:
space:
mode:
Diffstat (limited to 'askama_codegen')
-rw-r--r--askama_codegen/src/lib.rs37
-rw-r--r--askama_codegen/src/parser.rs30
2 files changed, 36 insertions, 31 deletions
diff --git a/askama_codegen/src/lib.rs b/askama_codegen/src/lib.rs
index 1e7fe71..72e51ba 100644
--- a/askama_codegen/src/lib.rs
+++ b/askama_codegen/src/lib.rs
@@ -7,7 +7,8 @@ extern crate proc_macro;
extern crate quote;
extern crate syn;
-use nom::IResult;
+mod parser;
+
use proc_macro::TokenStream;
use std::fs::File;
use std::io::Read;
@@ -53,28 +54,6 @@ fn get_template_source(tpl_file: &str) -> String {
s
}
-fn take_content(i: &[u8]) -> IResult<&[u8], &[u8]> {
- 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], &i[..]);
- } else if i[j + 1] == '{' as u8 {
- return IResult::Done(&i[j..], &i[..j]);
- } else if i[j + 1] == '%' as u8 {
- return IResult::Done(&i[j..], &i[..j]);
- }
- }
- }
- IResult::Done(&i[..0], &i[..])
-}
-
-named!(var_expr, delimited!(tag!("{{"), take_until!("}}"), tag!("}}")));
-
-named!(parse_template< Vec<&[u8]> >, many1!(alt!(take_content | var_expr)));
-
#[proc_macro_derive(Template, attributes(template))]
pub fn derive_template(input: TokenStream) -> TokenStream {
let source = input.to_string();
@@ -88,11 +67,7 @@ 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 root = match parse_template(src.as_bytes()) {
- IResult::Done(_, res) => res,
- _ => panic!("problems parsing template source"),
- };
+ let tokens = parser::parse(&src);
let mut code = String::new();
code.push_str("impl askama::Template for ");
@@ -101,13 +76,13 @@ pub fn derive_template(input: TokenStream) -> TokenStream {
code.push_str(" fn render(&self) -> String {\n");
code.push_str(" let mut buf = String::new();\n");
code.push_str(" buf.push_str(\"");
- code.push_str(str::from_utf8(root[0]).unwrap());
+ code.push_str(str::from_utf8(tokens[0]).unwrap());
code.push_str("\");\n");
code.push_str(" buf.push_str(&self.");
- code.push_str(str::from_utf8(root[1]).unwrap());
+ code.push_str(str::from_utf8(tokens[1]).unwrap());
code.push_str(");\n");
code.push_str(" buf.push_str(\"");
- code.push_str(str::from_utf8(root[2]).unwrap());
+ code.push_str(str::from_utf8(tokens[2]).unwrap());
code.push_str("\");\n");
code.push_str(" buf");
code.push_str(" }\n");
diff --git a/askama_codegen/src/parser.rs b/askama_codegen/src/parser.rs
new file mode 100644
index 0000000..6ff4388
--- /dev/null
+++ b/askama_codegen/src/parser.rs
@@ -0,0 +1,30 @@
+use nom::{self, IResult};
+
+fn take_content(i: &[u8]) -> IResult<&[u8], &[u8]> {
+ 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], &i[..]);
+ } else if i[j + 1] == '{' as u8 {
+ return IResult::Done(&i[j..], &i[..j]);
+ } else if i[j + 1] == '%' as u8 {
+ return IResult::Done(&i[j..], &i[..j]);
+ }
+ }
+ }
+ IResult::Done(&i[..0], &i[..])
+}
+
+named!(var_expr, delimited!(tag!("{{"), take_until!("}}"), tag!("}}")));
+
+named!(parse_template< Vec<&[u8]> >, many1!(alt!(take_content | var_expr)));
+
+pub fn parse<'a>(src: &'a str) -> Vec<&'a [u8]> {
+ match parse_template(src.as_bytes()) {
+ IResult::Done(_, res) => res,
+ _ => panic!("problems parsing template source"),
+ }
+}