diff options
Diffstat (limited to '')
| -rw-r--r-- | Cargo.lock | 6 | ||||
| -rw-r--r-- | README.md | 3 | ||||
| -rw-r--r-- | askama/Cargo.toml | 3 | ||||
| -rw-r--r-- | askama/src/lib.rs | 95 | ||||
| -rw-r--r-- | askama/src/path.rs | 49 | ||||
| -rw-r--r-- | askama_derive/Cargo.toml | 2 | ||||
| -rw-r--r-- | askama_derive/src/generator.rs (renamed from askama/src/generator.rs) | 0 | ||||
| -rw-r--r-- | askama_derive/src/lib.rs | 73 | ||||
| -rw-r--r-- | askama_derive/src/parser.rs (renamed from askama/src/parser.rs) | 0 | ||||
| -rw-r--r-- | askama_derive/src/path.rs | 19 | ||||
| -rw-r--r-- | testing/Cargo.toml | 1 | ||||
| -rw-r--r-- | testing/tests/filters.rs | 1 | ||||
| -rw-r--r-- | testing/tests/inheritance.rs | 3 | ||||
| -rw-r--r-- | testing/tests/operators.rs | 3 | ||||
| -rw-r--r-- | testing/tests/simple.rs | 1 | 
15 files changed, 131 insertions, 128 deletions
| @@ -3,22 +3,20 @@ name = "askama_testing"  version = "0.1.0"  dependencies = [   "askama 0.2.1", - "askama_derive 0.2.1",  ]  [[package]]  name = "askama"  version = "0.2.1"  dependencies = [ - "nom 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.11.8 (registry+https://github.com/rust-lang/crates.io-index)", + "askama_derive 0.2.1",  ]  [[package]]  name = "askama_derive"  version = "0.2.1"  dependencies = [ - "askama 0.2.1", + "nom 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",   "syn 0.11.8 (registry+https://github.com/rust-lang/crates.io-index)",  ] @@ -79,8 +79,7 @@ In any Rust file inside your crate, add the following:  ```rust  #[macro_use] -extern crate askama_derive; // for the custom derive implementation -extern crate askama; // for the Template trait +extern crate askama; // for the Template trait and custom derive macro  use askama::Template; // bring trait in scope diff --git a/askama/Cargo.toml b/askama/Cargo.toml index d17aa4e..4ea7a09 100644 --- a/askama/Cargo.toml +++ b/askama/Cargo.toml @@ -16,5 +16,4 @@ readme = "../README.md"  travis-ci = { repository = "djc/askama" }  [dependencies] -nom = "2.1" -syn = "0.11" +askama_derive = { path = "../askama_derive", version = "0.2.1" } diff --git a/askama/src/lib.rs b/askama/src/lib.rs index 8cfe79c..dff6a81 100644 --- a/askama/src/lib.rs +++ b/askama/src/lib.rs @@ -182,8 +182,12 @@  //! Expressions can be grouped using parentheses.  #[macro_use] -extern crate nom; -extern crate syn; +extern crate askama_derive; + +use std::env; +use std::fs::{self, DirEntry}; +use std::io; +use std::path::{Path, PathBuf};  /// Main `Template` trait; implementations are generally derived  pub trait Template { @@ -197,73 +201,42 @@ pub trait Template {      }  } -mod generator; -mod parser; -mod path; -  pub mod filters; -pub use path::rerun_if_templates_changed; +pub use askama_derive::*; -// Holds metadata for the template, based on the `template()` attribute. -struct TemplateMeta { -    path: String, -    print: String, +// Duplicates askama_derive::path::template_dir() +fn template_dir() -> PathBuf { +    let mut path = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); +    path.push("templates"); +    path  } -// Returns a `TemplateMeta` based on the `template()` attribute data found -// in the parsed struct or enum. Will panic if it does not find the required -// template path, or if the `print` key has an unexpected value. -fn get_template_meta(ast: &syn::DeriveInput) -> TemplateMeta { -    let mut path = None; -    let mut print = "none".to_string(); -    let attr = ast.attrs.iter().find(|a| a.name() == "template").unwrap(); -    if let syn::MetaItem::List(_, ref inner) = attr.value { -        for nm_item in inner { -            if let syn::NestedMetaItem::MetaItem(ref item) = *nm_item { -                if let syn::MetaItem::NameValue(ref key, ref val) = *item { -                    match key.as_ref() { -                        "path" => if let syn::Lit::Str(ref s, _) = *val { -                            path = Some(s.clone()); -                        } else { -                            panic!("template path must be string literal"); -                        }, -                        "print" => if let syn::Lit::Str(ref s, _) = *val { -                            print = s.clone(); -                        } else { -                            panic!("print value must be string literal"); -                        }, -                        _ => { panic!("unsupported annotation key found") } -                    } -                } +fn visit_dirs(dir: &Path, cb: &Fn(&DirEntry)) -> io::Result<()> { +    if dir.is_dir() { +        for entry in try!(fs::read_dir(dir)) { +            let entry = try!(entry); +            let path = entry.path(); +            if path.is_dir() { +                try!(visit_dirs(&path, cb)); +            } else { +                cb(&entry);              }          }      } -    if path.is_none() { -        panic!("template path not found in struct attributes"); -    } -    TemplateMeta { path: path.unwrap(), print: print } +    Ok(())  } -/// Takes a `syn::DeriveInput` and generates source code for it +/// Build script helper to rebuild crates if contained templates have changed  /// -/// Reads the metadata from the `template()` attribute to get the template -/// metadata, then fetches the source from the filesystem. The source is -/// parsed, and the parse tree is fed to the code generator. Will print -/// the parse tree and/or generated source according to the `print` key's -/// value as passed to the `template()` attribute. -pub fn build_template(ast: &syn::DeriveInput) -> String { -    let meta = get_template_meta(ast); -    let mut src = path::get_template_source(&meta.path); -    if src.ends_with('\n') { -        let _ = src.pop(); -    } -    let nodes = parser::parse(&src); -    if meta.print == "ast" || meta.print == "all" { -        println!("{:?}", nodes); -    } -    let code = generator::generate(ast, &meta.path, nodes); -    if meta.print == "code" || meta.print == "all" { -        println!("{}", code); -    } -    code +/// Iterates over all files in the template dir (`templates` in +/// `CARGO_MANIFEST_DIR`) and writes a `cargo:rerun-if-changed=` line for each +/// of them to stdout. +/// +/// This helper method can be used in build scripts (`build.rs`) in crates +/// that have templates, to make sure the crate gets rebuilt when template +/// source code changes. +pub fn rerun_if_templates_changed() { +    visit_dirs(&template_dir(), &|e: &DirEntry| { +        println!("cargo:rerun-if-changed={}", e.path().to_str().unwrap()); +    }).unwrap();  } diff --git a/askama/src/path.rs b/askama/src/path.rs deleted file mode 100644 index fb030e5..0000000 --- a/askama/src/path.rs +++ /dev/null @@ -1,49 +0,0 @@ -use std::env; -use std::fs::{self, DirEntry, File}; -use std::io::{self, Read}; -use std::path::{Path, PathBuf}; - -fn template_dir() -> PathBuf { -    let mut path = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); -    path.push("templates"); -    path -} - -pub fn get_template_source(tpl_file: &str) -> String { -    let mut path = template_dir(); -    path.push(Path::new(tpl_file)); -    let mut f = File::open(path).unwrap(); -    let mut s = String::new(); -    f.read_to_string(&mut s).unwrap(); -    s -} - -fn visit_dirs(dir: &Path, cb: &Fn(&DirEntry)) -> io::Result<()> { -    if dir.is_dir() { -        for entry in try!(fs::read_dir(dir)) { -            let entry = try!(entry); -            let path = entry.path(); -            if path.is_dir() { -                try!(visit_dirs(&path, cb)); -            } else { -                cb(&entry); -            } -        } -    } -    Ok(()) -} - -/// Build script helper to rebuild crates if contained templates have changed -/// -/// Iterates over all files in the template dir (`templates` in -/// `CARGO_MANIFEST_DIR`) and writes a `cargo:rerun-if-changed=` line for each -/// of them to stdout. -/// -/// This helper method can be used in build scripts (`build.rs`) in crates -/// that have templates, to make sure the crate gets rebuilt when template -/// source code changes. -pub fn rerun_if_templates_changed() { -    visit_dirs(&template_dir(), &|e: &DirEntry| { -        println!("cargo:rerun-if-changed={}", e.path().to_str().unwrap()); -    }).unwrap(); -} diff --git a/askama_derive/Cargo.toml b/askama_derive/Cargo.toml index 5018beb..605c40f 100644 --- a/askama_derive/Cargo.toml +++ b/askama_derive/Cargo.toml @@ -12,5 +12,5 @@ workspace = ".."  proc-macro = true  [dependencies] -askama = { path = "../askama", version = "0.2.1" } +nom = "2.1"  syn = "0.11" diff --git a/askama/src/generator.rs b/askama_derive/src/generator.rs index 16209cd..16209cd 100644 --- a/askama/src/generator.rs +++ b/askama_derive/src/generator.rs diff --git a/askama_derive/src/lib.rs b/askama_derive/src/lib.rs index 4b96e17..752978e 100644 --- a/askama_derive/src/lib.rs +++ b/askama_derive/src/lib.rs @@ -1,9 +1,78 @@ -extern crate askama; +#[macro_use] +extern crate nom;  extern crate proc_macro;  extern crate syn;  use proc_macro::TokenStream; +mod generator; +mod parser; +mod path; + +// Holds metadata for the template, based on the `template()` attribute. +struct TemplateMeta { +    path: String, +    print: String, +} + +// Returns a `TemplateMeta` based on the `template()` attribute data found +// in the parsed struct or enum. Will panic if it does not find the required +// template path, or if the `print` key has an unexpected value. +fn get_template_meta(ast: &syn::DeriveInput) -> TemplateMeta { +    let mut path = None; +    let mut print = "none".to_string(); +    let attr = ast.attrs.iter().find(|a| a.name() == "template").unwrap(); +    if let syn::MetaItem::List(_, ref inner) = attr.value { +        for nm_item in inner { +            if let syn::NestedMetaItem::MetaItem(ref item) = *nm_item { +                if let syn::MetaItem::NameValue(ref key, ref val) = *item { +                    match key.as_ref() { +                        "path" => if let syn::Lit::Str(ref s, _) = *val { +                            path = Some(s.clone()); +                        } else { +                            panic!("template path must be string literal"); +                        }, +                        "print" => if let syn::Lit::Str(ref s, _) = *val { +                            print = s.clone(); +                        } else { +                            panic!("print value must be string literal"); +                        }, +                        _ => { panic!("unsupported annotation key found") } +                    } +                } +            } +        } +    } +    if path.is_none() { +        panic!("template path not found in struct attributes"); +    } +    TemplateMeta { path: path.unwrap(), print: print } +} + +/// Takes a `syn::DeriveInput` and generates source code for it +/// +/// Reads the metadata from the `template()` attribute to get the template +/// metadata, then fetches the source from the filesystem. The source is +/// parsed, and the parse tree is fed to the code generator. Will print +/// the parse tree and/or generated source according to the `print` key's +/// value as passed to the `template()` attribute. +fn build_template(ast: &syn::DeriveInput) -> String { +    let meta = get_template_meta(ast); +    let mut src = path::get_template_source(&meta.path); +    if src.ends_with('\n') { +        let _ = src.pop(); +    } +    let nodes = parser::parse(&src); +    if meta.print == "ast" || meta.print == "all" { +        println!("{:?}", nodes); +    } +    let code = generator::generate(ast, &meta.path, nodes); +    if meta.print == "code" || meta.print == "all" { +        println!("{}", code); +    } +    code +} +  #[proc_macro_derive(Template, attributes(template))]  pub fn derive_template(input: TokenStream) -> TokenStream {      let ast = syn::parse_derive_input(&input.to_string()).unwrap(); @@ -11,5 +80,5 @@ pub fn derive_template(input: TokenStream) -> TokenStream {          syn::Body::Struct(ref data) => data,          _ => panic!("#[derive(Template)] can only be used with structs"),      }; -    askama::build_template(&ast).parse().unwrap() +    build_template(&ast).parse().unwrap()  } diff --git a/askama/src/parser.rs b/askama_derive/src/parser.rs index ce13add..ce13add 100644 --- a/askama/src/parser.rs +++ b/askama_derive/src/parser.rs diff --git a/askama_derive/src/path.rs b/askama_derive/src/path.rs new file mode 100644 index 0000000..96ed8c1 --- /dev/null +++ b/askama_derive/src/path.rs @@ -0,0 +1,19 @@ +use std::env; +use std::fs::File; +use std::io::Read; +use std::path::{Path, PathBuf}; + +fn template_dir() -> PathBuf { +    let mut path = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); +    path.push("templates"); +    path +} + +pub fn get_template_source(tpl_file: &str) -> String { +    let mut path = template_dir(); +    path.push(Path::new(tpl_file)); +    let mut f = File::open(path).unwrap(); +    let mut s = String::new(); +    f.read_to_string(&mut s).unwrap(); +    s +} diff --git a/testing/Cargo.toml b/testing/Cargo.toml index 8e7b1a7..bb6b534 100644 --- a/testing/Cargo.toml +++ b/testing/Cargo.toml @@ -7,7 +7,6 @@ build = "build.rs"  [dependencies]  askama = { path = "../askama", version = "*" } -askama_derive = { path = "../askama_derive", version = "*" }  [build-dependencies]  askama = { path = "../askama", version = "*" } diff --git a/testing/tests/filters.rs b/testing/tests/filters.rs index 5882bae..0b1b7c9 100644 --- a/testing/tests/filters.rs +++ b/testing/tests/filters.rs @@ -1,5 +1,4 @@  #[macro_use] -extern crate askama_derive;  extern crate askama;  use askama::Template; diff --git a/testing/tests/inheritance.rs b/testing/tests/inheritance.rs index b3add1c..459a5b2 100644 --- a/testing/tests/inheritance.rs +++ b/testing/tests/inheritance.rs @@ -1,6 +1,5 @@ -extern crate askama;  #[macro_use] -extern crate askama_derive; +extern crate askama;  use askama::Template; diff --git a/testing/tests/operators.rs b/testing/tests/operators.rs index 70d26b1..73b30b1 100644 --- a/testing/tests/operators.rs +++ b/testing/tests/operators.rs @@ -1,6 +1,5 @@ -extern crate askama;  #[macro_use] -extern crate askama_derive; +extern crate askama;  use askama::Template; diff --git a/testing/tests/simple.rs b/testing/tests/simple.rs index 60ecf05..a53257d 100644 --- a/testing/tests/simple.rs +++ b/testing/tests/simple.rs @@ -1,5 +1,4 @@  #[macro_use] -extern crate askama_derive;  extern crate askama;  use askama::Template; | 
