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 | 4587ba6ff7d4d65576a9125e067828a131ac0e4d (patch) | |
tree | 9bbe96c9cd07fc49353722afcd1242c1088bd382 /askama_derive | |
parent | 84a1960489c9c92ef898eb7617061035df39ac42 (diff) | |
download | askama-4587ba6ff7d4d65576a9125e067828a131ac0e4d.tar.gz askama-4587ba6ff7d4d65576a9125e067828a131ac0e4d.tar.bz2 askama-4587ba6ff7d4d65576a9125e067828a131ac0e4d.zip |
Move code generation into askama_shared
Diffstat (limited to '')
-rw-r--r-- | askama_derive/src/lib.rs | 154 | ||||
-rw-r--r-- | askama_shared/src/generator.rs (renamed from askama_derive/src/generator.rs) | 39 | ||||
-rw-r--r-- | askama_shared/templates/b.html (renamed from askama_derive/templates/b.html) | 0 |
3 files changed, 38 insertions, 155 deletions
diff --git a/askama_derive/src/lib.rs b/askama_derive/src/lib.rs index 0b64057..fcd857d 100644 --- a/askama_derive/src/lib.rs +++ b/askama_derive/src/lib.rs @@ -1,17 +1,13 @@ extern crate proc_macro; -#[macro_use] -extern crate quote; - -mod generator; +use askama_shared::heritage::{Context, Heritage}; use askama_shared::input::{Print, Source, TemplateInput}; -use askama_shared::parser::{parse, Expr, Macro, Node}; -use askama_shared::{read_config_file, Config}; +use askama_shared::parser::{parse, Expr, Node}; +use askama_shared::{generator, get_template_source, read_config_file, Config, Integrations}; use proc_macro::TokenStream; use std::collections::HashMap; -use std::fs; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; #[proc_macro_derive(Template, attributes(template))] pub fn derive_template(input: TokenStream) -> TokenStream { @@ -59,7 +55,7 @@ fn build_template(ast: &syn::DeriveInput) -> String { eprintln!("{:?}", parsed[&input.path]); } - let code = generator::generate(&input, &contexts, &heritage); + let code = generator::generate(&input, &contexts, &heritage, INTEGRATIONS); if input.print == Print::Code || input.print == Print::All { eprintln!("{}", code); } @@ -88,136 +84,10 @@ fn find_used_templates(input: &TemplateInput, map: &mut HashMap<PathBuf, String> } } -pub(crate) struct Heritage<'a> { - root: &'a Context<'a>, - blocks: BlockAncestry<'a>, -} - -impl<'a> Heritage<'a> { - fn new<'n>( - mut ctx: &'n Context<'n>, - contexts: &'n HashMap<&'n PathBuf, Context<'n>>, - ) -> Heritage<'n> { - let mut blocks: BlockAncestry<'n> = ctx - .blocks - .iter() - .map(|(name, def)| (*name, vec![(ctx, *def)])) - .collect(); - - while let Some(ref path) = ctx.extends { - ctx = &contexts[&path]; - for (name, def) in &ctx.blocks { - blocks - .entry(name) - .or_insert_with(|| vec![]) - .push((ctx, def)); - } - } - - Heritage { root: ctx, blocks } - } -} - -type BlockAncestry<'a> = HashMap<&'a str, Vec<(&'a Context<'a>, &'a Node<'a>)>>; - -pub(crate) struct Context<'a> { - nodes: &'a [Node<'a>], - extends: Option<PathBuf>, - blocks: HashMap<&'a str, &'a Node<'a>>, - macros: HashMap<&'a str, &'a Macro<'a>>, - imports: HashMap<&'a str, PathBuf>, -} - -impl<'a> Context<'a> { - fn new<'n>(config: &Config, path: &Path, nodes: &'n [Node<'n>]) -> Context<'n> { - let mut extends = None; - let mut blocks = Vec::new(); - let mut macros = HashMap::new(); - let mut imports = HashMap::new(); - - for n in nodes { - match n { - Node::Extends(Expr::StrLit(extends_path)) => match extends { - Some(_) => panic!("multiple extend blocks found"), - None => { - extends = Some(config.find_template(extends_path, Some(path))); - } - }, - def @ Node::BlockDef(_, _, _, _) => { - blocks.push(def); - } - Node::Macro(name, m) => { - macros.insert(*name, m); - } - Node::Import(_, import_path, scope) => { - let path = config.find_template(import_path, Some(path)); - imports.insert(*scope, path); - } - _ => {} - } - } - - let mut check_nested = 0; - let mut nested_blocks = Vec::new(); - while check_nested < blocks.len() { - if let Node::BlockDef(_, _, ref nodes, _) = blocks[check_nested] { - for n in nodes { - if let def @ Node::BlockDef(_, _, _, _) = n { - nested_blocks.push(def); - } - } - } else { - panic!("non block found in list of blocks"); - } - blocks.append(&mut nested_blocks); - check_nested += 1; - } - - let blocks: HashMap<_, _> = blocks - .iter() - .map(|def| { - if let Node::BlockDef(_, name, _, _) = def { - (*name, *def) - } else { - unreachable!() - } - }) - .collect(); - - Context { - nodes, - extends, - blocks, - macros, - imports, - } - } -} - -#[allow(clippy::match_wild_err_arm)] -fn get_template_source(tpl_path: &Path) -> String { - match fs::read_to_string(tpl_path) { - Err(_) => panic!( - "unable to open template file '{}'", - tpl_path.to_str().unwrap() - ), - Ok(mut source) => { - if source.ends_with('\n') { - let _ = source.pop(); - } - source - } - } -} - -#[cfg(test)] -mod tests { - use super::get_template_source; - use crate::Config; - - #[test] - fn get_source() { - let path = Config::new("").find_template("b.html", None); - assert_eq!(get_template_source(&path), "bar"); - } -} +const INTEGRATIONS: Integrations = Integrations { + actix: cfg!(feature = "actix-web"), + gotham: cfg!(feature = "gotham"), + iron: cfg!(feature = "iron"), + rocket: cfg!(feature = "rocket"), + warp: cfg!(feature = "warp"), +}; diff --git a/askama_derive/src/generator.rs b/askama_shared/src/generator.rs index a12b1f0..3171c38 100644 --- a/askama_derive/src/generator.rs +++ b/askama_shared/src/generator.rs @@ -1,13 +1,14 @@ -use super::{get_template_source, Context, Heritage}; -use askama_shared::filters; -use askama_shared::input::{Source, TemplateInput}; -use askama_shared::parser::{ +use super::{get_template_source, Integrations}; +use crate::filters; +use crate::heritage::{Context, Heritage}; +use crate::input::{Source, TemplateInput}; +use crate::parser::{ parse, Cond, Expr, MatchParameter, MatchParameters, MatchVariant, Node, Target, When, WS, }; use proc_macro2::Span; -use quote::ToTokens; +use quote::{quote, ToTokens}; use std::collections::{HashMap, HashSet}; use std::path::PathBuf; @@ -15,12 +16,14 @@ use std::{cmp, hash, mem, str}; use syn; -pub(crate) fn generate( +pub fn generate( input: &TemplateInput, contexts: &HashMap<&PathBuf, Context>, heritage: &Option<Heritage>, + integrations: Integrations, ) -> String { - Generator::new(input, contexts, heritage, SetChain::new()).build(&contexts[&input.path]) + Generator::new(input, contexts, heritage, integrations, SetChain::new()) + .build(&contexts[&input.path]) } struct Generator<'a> { @@ -30,6 +33,8 @@ struct Generator<'a> { contexts: &'a HashMap<&'a PathBuf, Context<'a>>, // The heritage contains references to blocks and their ancestry heritage: &'a Option<Heritage<'a>>, + // What integrations need to be generated + integrations: Integrations, // Variables accessible directly from the current scope (not redirected to context) locals: SetChain<'a, &'a str>, // Suffix whitespace from the previous literal. Will be flushed to the @@ -52,12 +57,14 @@ impl<'a> Generator<'a> { input: &'n TemplateInput, contexts: &'n HashMap<&'n PathBuf, Context<'n>>, heritage: &'n Option<Heritage>, + integrations: Integrations, locals: SetChain<'n, &'n str>, ) -> Generator<'n> { Generator { input, contexts, heritage, + integrations, locals, next_ws: None, skip_ws: false, @@ -69,7 +76,13 @@ impl<'a> Generator<'a> { fn child(&mut self) -> Generator { let locals = SetChain::with_parent(&self.locals); - Self::new(self.input, self.contexts, self.heritage, locals) + Self::new( + self.input, + self.contexts, + self.heritage, + self.integrations, + locals, + ) } // Takes a Context and generates the relevant implementations. @@ -83,19 +96,19 @@ impl<'a> Generator<'a> { self.impl_template(ctx, &mut buf); self.impl_display(&mut buf); - if cfg!(feature = "iron") { + if self.integrations.iron { self.impl_modifier_response(&mut buf); } - if cfg!(feature = "rocket") { + if self.integrations.rocket { self.impl_rocket_responder(&mut buf); } - if cfg!(feature = "actix-web") { + if self.integrations.actix { self.impl_actix_web_responder(&mut buf); } - if cfg!(feature = "gotham") { + if self.integrations.gotham { self.impl_gotham_into_response(&mut buf); } - if cfg!(feature = "warp") { + if self.integrations.warp { self.impl_warp_reply(&mut buf); } buf.buf diff --git a/askama_derive/templates/b.html b/askama_shared/templates/b.html index 5716ca5..5716ca5 100644 --- a/askama_derive/templates/b.html +++ b/askama_shared/templates/b.html |