diff options
Diffstat (limited to '')
| -rw-r--r-- | askama_shared/Cargo.toml | 4 | ||||
| -rw-r--r-- | askama_shared/src/generator.rs | 89 | ||||
| -rw-r--r-- | askama_shared/src/input.rs | 86 | ||||
| -rw-r--r-- | askama_shared/src/lib.rs | 2 | 
4 files changed, 72 insertions, 109 deletions
| diff --git a/askama_shared/Cargo.toml b/askama_shared/Cargo.toml index 41fe76b..0ce90b6 100644 --- a/askama_shared/Cargo.toml +++ b/askama_shared/Cargo.toml @@ -17,7 +17,7 @@ rocket = []  [dependencies]  error-chain = "0.11"  nom = "3" -quote = "0.3" +quote = "0.4"  serde = { version = "1.0", optional = true }  serde_json = { version = "1.0", optional = true } -syn = "0.11" +syn = "0.12" diff --git a/askama_shared/src/generator.rs b/askama_shared/src/generator.rs index a1b090d..e4eb9ec 100644 --- a/askama_shared/src/generator.rs +++ b/askama_shared/src/generator.rs @@ -81,9 +81,12 @@ fn trait_name_for_path(base: &Option<&Expr>, path: &Path) -> 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| { +fn get_parent_type<'a>(ast: &'a syn::DeriveInput) -> Option<&'a syn::Type> { +    match ast.data { +        syn::Data::Struct(syn::DataStruct { +            fields: syn::Fields::Named(ref fields), +            .. +        }) => fields.named.iter().filter_map(|f| {              f.ident.as_ref().and_then(|name| {                  if name.as_ref() == "_parent" {                      Some(&f.ty) @@ -180,11 +183,11 @@ impl<'a> Generator<'a> {      }      // Implement `Deref<Parent>` for an inheriting context struct. -    fn deref_to_parent(&mut self, state: &'a State, parent_type: &syn::Ty) { +    fn deref_to_parent(&mut self, state: &'a State, parent_type: &syn::Type) {          self.write_header(state, "::std::ops::Deref", &[]);          let mut tokens = Tokens::new();          parent_type.to_tokens(&mut tokens); -        self.writeln(&format!("type Target = {};", tokens.as_str())); +        self.writeln(&format!("type Target = {};", tokens));          self.writeln("fn deref(&self) -> &Self::Target {");          self.writeln("&self._parent");          self.writeln("}"); @@ -254,7 +257,7 @@ impl<'a> Generator<'a> {      // Implement Rocket's `Responder`.      fn impl_responder(&mut self, state: &'a State) { -        self.write_header(state, "::askama::rocket::Responder<'r>", &["'r"]); +        self.write_header(state, "::askama::rocket::Responder<'r>", &[quote!('r)]);          self.writeln("fn respond_to(self, _: &::askama::rocket::Request) \                        -> ::askama::rocket::Result<'r> {"); @@ -270,64 +273,22 @@ impl<'a> Generator<'a> {      // Writes header for the `impl` for `TraitFromPathName` or `Template`      // for the given context struct. -    fn write_header(&mut self, state: &'a State, target: &str, extra_anno: &[&str]) { -        let mut full_anno = Tokens::new(); -        let mut orig_anno = Tokens::new(); -        let need_anno = !state.input.ast.generics.lifetimes.is_empty() || -                        !state.input.ast.generics.ty_params.is_empty() || -                        !extra_anno.is_empty(); -        if need_anno { -            full_anno.append("<"); -            orig_anno.append("<"); -        } - -        let (mut full_sep, mut orig_sep) = (false, false); -        for lt in &state.input.ast.generics.lifetimes { -            if full_sep { -                full_anno.append(","); -            } -            if orig_sep { -                orig_anno.append(","); -            } -            lt.to_tokens(&mut full_anno); -            lt.to_tokens(&mut orig_anno); -            full_sep = true; -            orig_sep = true; -        } - -        for anno in extra_anno { -            if full_sep { -                full_anno.append(","); -            } -            full_anno.append(anno); -            full_sep = true; -        } - -        for param in &state.input.ast.generics.ty_params { -            if full_sep { -                full_anno.append(","); -            } -            if orig_sep { -                orig_anno.append(","); -            } -            let mut impl_param = param.clone(); -            impl_param.default = None; -            impl_param.to_tokens(&mut full_anno); -            param.ident.to_tokens(&mut orig_anno); -            full_sep = true; -            orig_sep = true; -        } - -        if need_anno { -            full_anno.append(">"); -            orig_anno.append(">"); -        } - -        let mut where_clause = Tokens::new(); -        state.input.ast.generics.where_clause.to_tokens(&mut where_clause); -        self.writeln(&format!("impl{} {} for {}{}{} {{", -                              full_anno.as_str(), target, state.input.ast.ident.as_ref(), -                              orig_anno.as_str(), where_clause.as_str())); +    fn write_header(&mut self, state: &'a State, target: &str, vars: &[Tokens]) { +        let mut generics = state.input.ast.generics.clone(); +        for v in vars.iter() { +            generics.params.push_value(parse_quote!(#v)); +        } +        let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); +        let ident = state.input.ast.ident.as_ref(); +        self.writeln( +            format!( +                "{} {} for {}{} {{", +                quote!(impl#impl_generics), +                target, +                ident, +                quote!(#ty_generics #where_clause), +            ).as_ref(), +        );      }      /* Helper methods for handling node types */ diff --git a/askama_shared/src/input.rs b/askama_shared/src/input.rs index 25382cb..e3b64da 100644 --- a/askama_shared/src/input.rs +++ b/askama_shared/src/input.rs @@ -1,6 +1,5 @@  use path; -use std::borrow::Cow;  use std::path::{Path, PathBuf};  use syn; @@ -8,26 +7,26 @@ use syn;  pub struct TemplateInput<'a> {      pub ast: &'a syn::DeriveInput, -    pub meta: TemplateMeta<'a>, +    pub meta: TemplateMeta,      pub path: PathBuf, -    pub source: Cow<'a, str>, +    pub source: String,  }  impl<'a> TemplateInput<'a> {      pub fn new(ast: &'a syn::DeriveInput) -> TemplateInput<'a> {          let meta = TemplateMeta::new(ast);          let (path, source) = match meta.source { -            Source::Source(s) => { +            Source::Source(ref s) => {                  let path = match meta.ext { -                    Some(v) => PathBuf::from(format!("_.{}", v)), +                    Some(ref v) => PathBuf::from(format!("_.{}", v)),                      None => PathBuf::new(),                  }; -                (path, Cow::Borrowed(s)) +                (path, s.clone())              }, -            Source::Path(s) => { -                let path = path::find_template_from_path(s, None); +            Source::Path(ref s) => { +                let path = path::find_template_from_path(&s, None);                  let src = path::get_template_source(&path); -                (path, Cow::Owned(src)) +                (path, src)              },          };          TemplateInput { ast, meta, path, source } @@ -35,16 +34,18 @@ impl<'a> TemplateInput<'a> {  }  // Holds metadata for the template, based on the `template()` attribute. -pub struct TemplateMeta<'a> { -    source: Source<'a>, +pub struct TemplateMeta { +    source: Source,      pub print: Print,      pub escaping: EscapeMode, -    pub ext: Option<&'a str>, +    pub ext: Option<String>,  } -impl<'a> TemplateMeta<'a> { -    fn new(ast: &'a syn::DeriveInput) -> TemplateMeta<'a> { -        let attr = ast.attrs.iter().find(|a| a.name() == "template"); +impl TemplateMeta { +    fn new(ast: &syn::DeriveInput) -> TemplateMeta { +        let attr = ast.attrs +            .iter() +            .find(|a| a.interpret_meta().unwrap().name() == "template");          if attr.is_none() {              let msg = format!("'template' attribute not found on struct '{}'",                                ast.ident.as_ref()); @@ -56,39 +57,39 @@ impl<'a> TemplateMeta<'a> {          let mut print = Print::None;          let mut escaping = None;          let mut ext = None; -        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 { +        if let syn::Meta::List(ref inner) = attr.interpret_meta().unwrap() { +            for nm_item in inner.nested.iter() { +                if let syn::NestedMeta::Meta(ref item) = *nm_item { +                    if let syn::Meta::NameValue(ref pair) = *item { +                        match pair.ident.as_ref() { +                            "path" => if let syn::Lit::Str(ref s) = pair.lit {                                  if source.is_some() {                                      panic!("must specify 'source' or 'path', not both");                                  } -                                source = Some(Source::Path(s.as_ref())); +                                source = Some(Source::Path(s.value()));                              } else {                                  panic!("template path must be string literal");                              }, -                            "source" => if let syn::Lit::Str(ref s, _) = *val { +                            "source" => if let syn::Lit::Str(ref s) = pair.lit {                                  if source.is_some() {                                      panic!("must specify 'source' or 'path', not both");                                  } -                                source = Some(Source::Source(s.as_ref())); +                                source = Some(Source::Source(s.value()));                              } else {                                  panic!("template source must be string literal");                              }, -                            "print" => if let syn::Lit::Str(ref s, _) = *val { -                                print = (s.as_ref() as &str).into(); +                            "print" => if let syn::Lit::Str(ref s) = pair.lit { +                                print = s.value().into();                              } else {                                  panic!("print value must be string literal");                              }, -                            "escape" => if let syn::Lit::Str(ref s, _) = *val { -                                escaping = Some((s.as_ref() as &str).into()); +                            "escape" => if let syn::Lit::Str(ref s) = pair.lit { +                                escaping = Some(s.value().into());                              } else {                                  panic!("escape value must be string literal");                              }, -                            "ext" => if let syn::Lit::Str(ref s, _) = *val { -                                ext = Some((s.as_ref() as &str).into()); +                            "ext" => if let syn::Lit::Str(ref s) = pair.lit { +                                ext = Some(s.value());                              } else {                                  panic!("ext value must be string literal");                              }, @@ -113,10 +114,9 @@ impl<'a> TemplateMeta<'a> {              Some(m) => m,              None => {                  let ext = match source { -                    Source::Path(p) => { -                        Path::new(p).extension().map(|s| s.to_str().unwrap()).unwrap_or("") -                    }, -                    Source::Source(_) => ext.unwrap(), // Already panicked if None +                    Source::Path(ref p) => +                        Path::new(p).extension().map(|s| s.to_str().unwrap()).unwrap_or(""), +                    Source::Source(_) => ext.as_ref().unwrap(), // Already panicked if None                  };                  if HTML_EXTENSIONS.contains(&ext) {                      EscapeMode::Html @@ -129,9 +129,9 @@ impl<'a> TemplateMeta<'a> {      }  } -enum Source<'a> { -    Path(&'a str), -    Source(&'a str), +enum Source { +    Path(String), +    Source(String),  }  #[derive(PartialEq)] @@ -140,10 +140,10 @@ pub enum EscapeMode {      None,  } -impl<'a> From<&'a str> for EscapeMode { -    fn from(s: &'a str) -> EscapeMode { +impl From<String> for EscapeMode { +    fn from(s: String) -> EscapeMode {          use self::EscapeMode::*; -        match s { +        match s.as_ref() {              "html" => Html,              "none" => None,              v => panic!("invalid value for escape option: {}", v), @@ -159,10 +159,10 @@ pub enum Print {      None,  } -impl<'a> From<&'a str> for Print { -    fn from(s: &'a str) -> Print { +impl From<String> for Print { +    fn from(s: String) -> Print {          use self::Print::*; -        match s { +        match s.as_ref() {              "all" => All,              "ast" => Ast,              "code" => Code, diff --git a/askama_shared/src/lib.rs b/askama_shared/src/lib.rs index 0f46b91..ed2357d 100644 --- a/askama_shared/src/lib.rs +++ b/askama_shared/src/lib.rs @@ -2,7 +2,9 @@  extern crate error_chain;  #[macro_use]  extern crate nom; +#[macro_use]  extern crate quote; +#[macro_use(parse_quote)]  extern crate syn;  #[cfg(feature = "serde-json")] | 
