From c927d51fe10a2050e0afd143e300615facd781b7 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Wed, 8 Mar 2017 19:55:19 +0100 Subject: Copy type parameters and where clauses (fixes #11) --- askama_derive/Cargo.toml | 1 + askama_derive/src/generator.rs | 48 ++++++++++++++++++++++++++++++++++-------- askama_derive/src/lib.rs | 1 + 3 files changed, 41 insertions(+), 9 deletions(-) (limited to 'askama_derive') diff --git a/askama_derive/Cargo.toml b/askama_derive/Cargo.toml index 605c40f..6e0cc3c 100644 --- a/askama_derive/Cargo.toml +++ b/askama_derive/Cargo.toml @@ -14,3 +14,4 @@ proc-macro = true [dependencies] nom = "2.1" syn = "0.11" +quote = "0.3" diff --git a/askama_derive/src/generator.rs b/askama_derive/src/generator.rs index af07470..2eed03f 100644 --- a/askama_derive/src/generator.rs +++ b/askama_derive/src/generator.rs @@ -2,6 +2,7 @@ use parser::{Cond, Expr, Node, Target, WS}; use std::str; use std::collections::HashSet; use syn; +use quote::{Tokens, ToTokens}; fn path_as_identifier(s: &str) -> String { let mut res = String::new(); @@ -308,22 +309,51 @@ impl<'a> Generator<'a> { fn write_header(&mut self, ast: &syn::DeriveInput, trait_suffix: Option<&str>) { - let mut anno = String::new(); - if ast.generics.lifetimes.len() > 0 { - anno.push('<'); - for lt in &ast.generics.lifetimes { - anno.push_str(lt.lifetime.ident.as_ref()); + let mut full_anno = Tokens::new(); + let mut orig_anno = Tokens::new(); + let need_anno = ast.generics.lifetimes.len() > 0 || + ast.generics.ty_params.len() > 0; + if need_anno { + full_anno.append("<"); + orig_anno.append("<"); + } + + let mut sep = false; + for lt in &ast.generics.lifetimes { + if sep { + full_anno.append(","); + orig_anno.append(","); } - anno.push('>'); - }; + lt.to_tokens(&mut full_anno); + lt.to_tokens(&mut orig_anno); + sep = true; + } + + for param in &ast.generics.ty_params { + if sep { + full_anno.append(","); + orig_anno.append(","); + } + param.to_tokens(&mut full_anno); + param.ident.to_tokens(&mut orig_anno); + sep = true; + } + + if need_anno { + full_anno.append(">"); + orig_anno.append(">"); + } + let mut where_clause = Tokens::new(); + ast.generics.where_clause.to_tokens(&mut where_clause); let name = if trait_suffix.is_some() { format!("TraitFrom{}", trait_suffix.unwrap()) } else { "askama::Template".to_string() }; - self.writeln(&format!("impl{} {} for {}{} {{", - anno, &name, ast.ident.as_ref(), anno)); + self.writeln(&format!("impl{} {} for {}{}{} {{", + full_anno.as_str(), &name, ast.ident.as_ref(), + orig_anno.as_str(), where_clause.as_str())); } fn impl_template(&mut self, ast: &syn::DeriveInput, nodes: &'a [Node]) { diff --git a/askama_derive/src/lib.rs b/askama_derive/src/lib.rs index f823299..370c24d 100644 --- a/askama_derive/src/lib.rs +++ b/askama_derive/src/lib.rs @@ -1,6 +1,7 @@ #[macro_use] extern crate nom; extern crate proc_macro; +extern crate quote; extern crate syn; use proc_macro::TokenStream; -- cgit