diff options
| author | 2017-08-08 20:29:43 +0200 | |
|---|---|---|
| committer | 2017-08-08 20:29:43 +0200 | |
| commit | d40f5a3ea60a1f8c9d02c955835cb966873b4082 (patch) | |
| tree | d13d856e05e34791e2912f60f8583399ce4b0b8d /askama_derive/src | |
| parent | 946e8c758729c5fce42b137a2bc7e31b8bd49ade (diff) | |
| download | askama-d40f5a3ea60a1f8c9d02c955835cb966873b4082.tar.gz askama-d40f5a3ea60a1f8c9d02c955835cb966873b4082.tar.bz2 askama-d40f5a3ea60a1f8c9d02c955835cb966873b4082.zip  | |
Reorganize code order in askama_derive modules
Diffstat (limited to '')
| -rw-r--r-- | askama_derive/src/generator.rs | 164 | ||||
| -rw-r--r-- | askama_derive/src/lib.rs | 68 | ||||
| -rw-r--r-- | askama_derive/src/path.rs | 42 | 
3 files changed, 137 insertions, 137 deletions
diff --git a/askama_derive/src/generator.rs b/askama_derive/src/generator.rs index 6c53a89..de2e6f2 100644 --- a/askama_derive/src/generator.rs +++ b/askama_derive/src/generator.rs @@ -9,6 +9,88 @@ use std::collections::HashSet;  use syn; +pub fn generate(ast: &syn::DeriveInput, path: &str, mut nodes: Vec<Node>) -> String { +    let mut base: Option<Expr> = None; +    let mut blocks = Vec::new(); +    let mut block_names = Vec::new(); +    let mut content = Vec::new(); +    for n in nodes.drain(..) { +        match n { +            Node::Extends(path) => { +                match base { +                    Some(_) => panic!("multiple extend blocks found"), +                    None => { base = Some(path); }, +                } +            }, +            Node::BlockDef(ws1, name, _, ws2) => { +                blocks.push(n); +                block_names.push(name); +                content.push(Node::Block(ws1, name, ws2)); +            }, +            _ => { content.push(n); }, +        } +    } + +    let mut locals = HashSet::new(); +    let mut gen = Generator::default(&mut locals); +    if !blocks.is_empty() { +        let trait_name = trait_name_for_path(&base, path); +        if base.is_none() { +            gen.define_trait(&trait_name, &block_names); +        } else { +            gen.deref_to_parent(ast, &get_parent_type(ast).unwrap()); +        } + +        let trait_nodes = if base.is_none() { Some(&content[..]) } else { None }; +        gen.impl_trait(ast, &trait_name, &blocks, trait_nodes); +        gen.impl_template_for_trait(ast, base.is_some()); +    } else { +        gen.impl_template(ast, &content); +    } +    gen.result() +} + +fn trait_name_for_path(base: &Option<Expr>, path: &str) -> String { +    let rooted_path = match *base { +        Some(Expr::StrLit(user_path)) => { +            path::find_template_from_path(user_path, Some(path)) +        }, +        _ => { +            let mut path_buf = PathBuf::new(); +            path_buf.push(&path); +            path_buf +        }, +    }; + +    let mut res = String::new(); +    res.push_str("TraitFrom"); +    for c in rooted_path.to_string_lossy().chars() { +        if c.is_alphanumeric() { +            res.push(c); +        } else { +            res.push_str(&format!("{:x}", c as u32)); +        } +    } +    res +} + +fn get_parent_type(ast: &syn::DeriveInput) -> Option<&syn::Ty> { +    match ast.body { +        syn::Body::Struct(ref data) => { +            data.fields().iter().filter_map(|f| { +                f.ident.as_ref().and_then(|name| { +                    if name.as_ref() == "_parent" { +                        Some(&f.ty) +                    } else { +                        None +                    } +                }) +            }) +        }, +        _ => panic!("derive(Template) only works for struct items"), +    }.next() +} +  struct Generator<'a> {      buf: String,      indent: u8, @@ -451,85 +533,3 @@ impl<'a> Generator<'a> {      }  } - -fn trait_name_for_path(base: &Option<Expr>, path: &str) -> String { -    let rooted_path = match *base { -        Some(Expr::StrLit(user_path)) => { -            path::find_template_from_path(user_path, Some(path)) -        }, -        _ => { -            let mut path_buf = PathBuf::new(); -            path_buf.push(&path); -            path_buf -        }, -    }; - -    let mut res = String::new(); -    res.push_str("TraitFrom"); -    for c in rooted_path.to_string_lossy().chars() { -        if c.is_alphanumeric() { -            res.push(c); -        } else { -            res.push_str(&format!("{:x}", c as u32)); -        } -    } -    res -} - -fn get_parent_type(ast: &syn::DeriveInput) -> Option<&syn::Ty> { -    match ast.body { -        syn::Body::Struct(ref data) => { -            data.fields().iter().filter_map(|f| { -                f.ident.as_ref().and_then(|name| { -                    if name.as_ref() == "_parent" { -                        Some(&f.ty) -                    } else { -                        None -                    } -                }) -            }) -        }, -        _ => panic!("derive(Template) only works for struct items"), -    }.next() -} - -pub fn generate(ast: &syn::DeriveInput, path: &str, mut nodes: Vec<Node>) -> String { -    let mut base: Option<Expr> = None; -    let mut blocks = Vec::new(); -    let mut block_names = Vec::new(); -    let mut content = Vec::new(); -    for n in nodes.drain(..) { -        match n { -            Node::Extends(path) => { -                match base { -                    Some(_) => panic!("multiple extend blocks found"), -                    None => { base = Some(path); }, -                } -            }, -            Node::BlockDef(ws1, name, _, ws2) => { -                blocks.push(n); -                block_names.push(name); -                content.push(Node::Block(ws1, name, ws2)); -            }, -            _ => { content.push(n); }, -        } -    } - -    let mut locals = HashSet::new(); -    let mut gen = Generator::default(&mut locals); -    if !blocks.is_empty() { -        let trait_name = trait_name_for_path(&base, path); -        if base.is_none() { -            gen.define_trait(&trait_name, &block_names); -        } else { -            gen.deref_to_parent(ast, &get_parent_type(ast).unwrap()); -        } - -        let trait_nodes = if base.is_none() { Some(&content[..]) } else { None }; -        gen.impl_trait(ast, &trait_name, &blocks, trait_nodes); -        gen.impl_template_for_trait(ast, base.is_some()); -    } else { -        gen.impl_template(ast, &content); -    } -    gen.result() -} diff --git a/askama_derive/src/lib.rs b/askama_derive/src/lib.rs index 5ee5a4c..ad0e218 100644 --- a/askama_derive/src/lib.rs +++ b/askama_derive/src/lib.rs @@ -10,10 +10,36 @@ mod generator;  mod parser;  mod path; -// Holds metadata for the template, based on the `template()` attribute. -struct TemplateMeta { -    path: String, -    print: String, +#[proc_macro_derive(Template, attributes(template))] +pub fn derive_template(input: TokenStream) -> TokenStream { +    let ast = syn::parse_derive_input(&input.to_string()).unwrap(); +    match ast.body { +        syn::Body::Struct(ref data) => data, +        _ => panic!("#[derive(Template)] can only be used with structs"), +    }; +    build_template(&ast).parse().unwrap() +} + +/// 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 path = path::find_template_from_path(&meta.path, None); +    let src = path::get_template_source(&path); +    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  }  // Returns a `TemplateMeta` based on the `template()` attribute data found @@ -57,34 +83,8 @@ fn get_template_meta(ast: &syn::DeriveInput) -> TemplateMeta {      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 path = path::find_template_from_path(&meta.path, None); -    let src = path::get_template_source(&path); -    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(); -    match ast.body { -        syn::Body::Struct(ref data) => data, -        _ => panic!("#[derive(Template)] can only be used with structs"), -    }; -    build_template(&ast).parse().unwrap() +// Holds metadata for the template, based on the `template()` attribute. +struct TemplateMeta { +    path: String, +    print: String,  } diff --git a/askama_derive/src/path.rs b/askama_derive/src/path.rs index b51f5f3..03ab20d 100644 --- a/askama_derive/src/path.rs +++ b/askama_derive/src/path.rs @@ -3,10 +3,23 @@ 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_path: &Path) -> String { +    let mut path = template_dir(); +    path.push(tpl_path); +    let mut f = match File::open(&path) { +        Err(_) => { +            let msg = format!("unable to open template file '{}'", +                              &path.to_str().unwrap()); +            panic!(msg); +        }, +        Ok(f) => f, +    }; +    let mut s = String::new(); +    f.read_to_string(&mut s).unwrap(); +    if s.ends_with('\n') { +        let _ = s.pop(); +    } +    s  }  pub fn find_template_from_path<'a>(path: &str, start_at: Option<&str>) -> PathBuf { @@ -33,23 +46,10 @@ pub fn find_template_from_path<'a>(path: &str, start_at: Option<&str>) -> PathBu      }  } -pub fn get_template_source(tpl_path: &Path) -> String { -    let mut path = template_dir(); -    path.push(tpl_path); -    let mut f = match File::open(&path) { -        Err(_) => { -            let msg = format!("unable to open template file '{}'", -                              &path.to_str().unwrap()); -            panic!(msg); -        }, -        Ok(f) => f, -    }; -    let mut s = String::new(); -    f.read_to_string(&mut s).unwrap(); -    if s.ends_with('\n') { -        let _ = s.pop(); -    } -    s +fn template_dir() -> PathBuf { +    let mut path = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); +    path.push("templates"); +    path  }  #[cfg(test)]  | 
