diff options
author | Dirkjan Ochtman <dirkjan@ochtman.nl> | 2020-01-29 21:49:42 +0100 |
---|---|---|
committer | Dirkjan Ochtman <dirkjan@ochtman.nl> | 2020-01-29 21:49:44 +0100 |
commit | 84a1960489c9c92ef898eb7617061035df39ac42 (patch) | |
tree | 599bee592dbffdb5e1365e4aa9bf4f77f16d4611 /askama_derive | |
parent | cb660c7b8d398800d91d7c4c6c3276959fd14e71 (diff) | |
download | askama-84a1960489c9c92ef898eb7617061035df39ac42.tar.gz askama-84a1960489c9c92ef898eb7617061035df39ac42.tar.bz2 askama-84a1960489c9c92ef898eb7617061035df39ac42.zip |
Move input module into askama_shared
Diffstat (limited to 'askama_derive')
-rw-r--r-- | askama_derive/src/generator.rs | 2 | ||||
-rw-r--r-- | askama_derive/src/input.rs | 221 | ||||
-rw-r--r-- | askama_derive/src/lib.rs | 3 |
3 files changed, 2 insertions, 224 deletions
diff --git a/askama_derive/src/generator.rs b/askama_derive/src/generator.rs index 4f5b495..a12b1f0 100644 --- a/askama_derive/src/generator.rs +++ b/askama_derive/src/generator.rs @@ -1,6 +1,6 @@ use super::{get_template_source, Context, Heritage}; -use crate::input::{Source, TemplateInput}; use askama_shared::filters; +use askama_shared::input::{Source, TemplateInput}; use askama_shared::parser::{ parse, Cond, Expr, MatchParameter, MatchParameters, MatchVariant, Node, Target, When, WS, }; diff --git a/askama_derive/src/input.rs b/askama_derive/src/input.rs deleted file mode 100644 index 6a54a99..0000000 --- a/askama_derive/src/input.rs +++ /dev/null @@ -1,221 +0,0 @@ -use askama_shared::{Config, Syntax}; - -use std::path::PathBuf; - -use quote::ToTokens; -use syn; - -pub struct TemplateInput<'a> { - pub ast: &'a syn::DeriveInput, - pub config: &'a Config<'a>, - pub syntax: &'a Syntax<'a>, - pub source: Source, - pub print: Print, - pub escaper: &'a str, - pub ext: Option<String>, - pub parent: Option<&'a syn::Type>, - pub path: PathBuf, -} - -impl<'a> TemplateInput<'a> { - /// Extract the template metadata from the `DeriveInput` structure. This - /// mostly recovers the data for the `TemplateInput` fields from the - /// `template()` attribute list fields; it also finds the of the `_parent` - /// field, if any. - pub fn new<'n>(ast: &'n syn::DeriveInput, config: &'n Config) -> TemplateInput<'n> { - // Check that an attribute called `template()` exists and that it is - // the proper type (list). - let meta = ast - .attrs - .iter() - .find_map(|attr| match attr.parse_meta() { - Ok(m) => { - if m.path().is_ident("template") { - Some(m) - } else { - None - } - } - Err(e) => panic!("unable to parse attribute: {}", e), - }) - .expect("no attribute 'template' found"); - - let meta_list = match meta { - syn::Meta::List(inner) => inner, - _ => panic!("attribute 'template' has incorrect type"), - }; - - // Loop over the meta attributes and find everything that we - // understand. Raise panics if something is not right. - // `source` contains an enum that can represent `path` or `source`. - let mut source = None; - let mut print = Print::None; - let mut escaping = None; - let mut ext = None; - let mut syntax = None; - for item in meta_list.nested { - let pair = match item { - syn::NestedMeta::Meta(syn::Meta::NameValue(ref pair)) => pair, - _ => panic!( - "unsupported attribute argument {:?}", - item.to_token_stream() - ), - }; - - if pair.path.is_ident("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.value())); - } else { - panic!("template path must be string literal"); - } - } else if pair.path.is_ident("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.value())); - } else { - panic!("template source must be string literal"); - } - } else if pair.path.is_ident("print") { - if let syn::Lit::Str(ref s) = pair.lit { - print = s.value().into(); - } else { - panic!("print value must be string literal"); - } - } else if pair.path.is_ident("escape") { - if let syn::Lit::Str(ref s) = pair.lit { - escaping = Some(s.value()); - } else { - panic!("escape value must be string literal"); - } - } else if pair.path.is_ident("ext") { - if let syn::Lit::Str(ref s) = pair.lit { - ext = Some(s.value()); - } else { - panic!("ext value must be string literal"); - } - } else if pair.path.is_ident("syntax") { - if let syn::Lit::Str(ref s) = pair.lit { - syntax = Some(s.value()) - } else { - panic!("syntax value must be string literal"); - } - } else { - panic!( - "unsupported attribute key '{}' found", - pair.path.to_token_stream() - ) - } - } - - // Validate the `source` and `ext` value together, since they are - // related. In case `source` was used instead of `path`, the value - // of `ext` is merged into a synthetic `path` value here. - let source = source.expect("template path or source not found in attributes"); - let path = match (&source, &ext) { - (&Source::Path(ref path), None) => config.find_template(path, None), - (&Source::Source(_), Some(ext)) => PathBuf::from(format!("{}.{}", ast.ident, ext)), - (&Source::Path(_), Some(_)) => { - panic!("'ext' attribute cannot be used with 'path' attribute") - } - (&Source::Source(_), None) => { - panic!("must include 'ext' attribute when using 'source' attribute") - } - }; - - // Check to see if a `_parent` field was defined on the context - // struct, and store the type for it for use in the code generator. - let parent = match ast.data { - syn::Data::Struct(syn::DataStruct { - fields: syn::Fields::Named(ref fields), - .. - }) => fields - .named - .iter() - .find(|f| f.ident.as_ref().filter(|name| *name == "_parent").is_some()) - .map(|f| &f.ty), - _ => None, - }; - - if parent.is_some() { - eprint!( - " --> in struct {}\n = use of deprecated field '_parent'\n", - ast.ident - ); - } - - // Validate syntax - let syntax = syntax.map_or_else( - || config.syntaxes.get(config.default_syntax).unwrap(), - |s| { - config - .syntaxes - .get(&s) - .unwrap_or_else(|| panic!("attribute syntax {} not exist", s)) - }, - ); - - // Match extension against defined output formats - - let extension = escaping.unwrap_or_else(|| { - path.extension() - .map(|s| s.to_str().unwrap()) - .unwrap_or("") - .to_string() - }); - - let mut escaper = None; - for (extensions, path) in &config.escapers { - if extensions.contains(&extension) { - escaper = Some(path); - break; - } - } - - let escaper = escaper.unwrap_or_else(|| { - panic!("no escaper defined for extension '{}'", extension); - }); - - TemplateInput { - ast, - config, - source, - print, - escaper, - ext, - parent, - path, - syntax, - } - } -} - -pub enum Source { - Path(String), - Source(String), -} - -#[derive(PartialEq)] -pub enum Print { - All, - Ast, - Code, - None, -} - -impl From<String> for Print { - fn from(s: String) -> Print { - use self::Print::*; - match s.as_ref() { - "all" => All, - "ast" => Ast, - "code" => Code, - "none" => None, - v => panic!("invalid value for print option: {}", v), - } - } -} diff --git a/askama_derive/src/lib.rs b/askama_derive/src/lib.rs index 2189458..0b64057 100644 --- a/askama_derive/src/lib.rs +++ b/askama_derive/src/lib.rs @@ -3,9 +3,8 @@ extern crate proc_macro; extern crate quote; mod generator; -mod input; -use crate::input::{Print, Source, TemplateInput}; +use askama_shared::input::{Print, Source, TemplateInput}; use askama_shared::parser::{parse, Expr, Macro, Node}; use askama_shared::{read_config_file, Config}; use proc_macro::TokenStream; |