diff options
| author | 2017-08-08 12:35:15 +0200 | |
|---|---|---|
| committer | 2017-08-08 12:36:29 +0200 | |
| commit | e3d08c72bc2a7c34243208e68158b6f919701082 (patch) | |
| tree | 72bac8ca70162e50240a82b660669048edbb89e4 /askama_derive/src | |
| parent | 20efa67bc1120f34a3f5be2015090e8ee818ddd5 (diff) | |
| download | askama-e3d08c72bc2a7c34243208e68158b6f919701082.tar.gz askama-e3d08c72bc2a7c34243208e68158b6f919701082.tar.bz2 askama-e3d08c72bc2a7c34243208e68158b6f919701082.zip | |
Implement Deref<Parent> for inheriting templates (fixes #28)
Diffstat (limited to '')
| -rw-r--r-- | askama_derive/src/generator.rs | 31 | 
1 files changed, 31 insertions, 0 deletions
| diff --git a/askama_derive/src/generator.rs b/askama_derive/src/generator.rs index a3363b4..fd2fb5b 100644 --- a/askama_derive/src/generator.rs +++ b/askama_derive/src/generator.rs @@ -379,6 +379,18 @@ impl<'a> Generator<'a> {          self.writeln("}");      } +    // Implement `Deref<Parent>` for an inheriting context struct. +    fn deref_to_parent(&mut self, ast: &syn::DeriveInput, parent_type: &syn::Ty) { +        self.write_header(ast, "::std::ops::Deref"); +        let mut tokens = Tokens::new(); +        parent_type.to_tokens(&mut tokens); +        self.writeln(&format!("type Target = {};", tokens.as_str())); +        self.writeln("fn deref(&self) -> &Self::Target {"); +        self.writeln("&self._parent"); +        self.writeln("}"); +        self.writeln("}"); +    } +      // Implement `TraitFromPathName` for the given context struct.      fn impl_trait(&mut self, ast: &syn::DeriveInput, trait_name: &str,                    blocks: &'a [Node], nodes: Option<&'a [Node]>) { @@ -461,6 +473,23 @@ fn trait_name_for_path(base: &Option<Expr>, path: &str) -> String {      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(); @@ -489,6 +518,8 @@ pub fn generate(ast: &syn::DeriveInput, path: &str, mut nodes: Vec<Node>) -> Str          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 }; | 
