mirror of
				https://github.com/askama-rs/askama.git
				synced 2025-11-04 07:23:15 +00:00 
			
		
		
		
	Fix formatting with cargo fmt
This commit is contained in:
		
							parent
							
								
									f05a924c49
								
							
						
					
					
						commit
						31b90ccc65
					
				@ -338,16 +338,16 @@ pub trait Template {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub use shared::filters;
 | 
					 | 
				
			||||||
pub use askama_derive::*;
 | 
					pub use askama_derive::*;
 | 
				
			||||||
 | 
					pub use shared::filters;
 | 
				
			||||||
pub use shared::{Error, MarkupDisplay, Result};
 | 
					pub use shared::{Error, MarkupDisplay, Result};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg(feature = "with-iron")]
 | 
					#[cfg(feature = "with-iron")]
 | 
				
			||||||
pub mod iron {
 | 
					pub mod iron {
 | 
				
			||||||
    extern crate iron;
 | 
					    extern crate iron;
 | 
				
			||||||
 | 
					    pub use self::iron::headers::ContentType;
 | 
				
			||||||
    pub use self::iron::modifier::Modifier;
 | 
					    pub use self::iron::modifier::Modifier;
 | 
				
			||||||
    pub use self::iron::response::Response;
 | 
					    pub use self::iron::response::Response;
 | 
				
			||||||
    pub use self::iron::headers::ContentType;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg(feature = "with-rocket")]
 | 
					#[cfg(feature = "with-rocket")]
 | 
				
			||||||
 | 
				
			|||||||
@ -2,16 +2,15 @@ use input::TemplateInput;
 | 
				
			|||||||
use parser::{self, Cond, Expr, Macro, MatchParameter, MatchVariant, Node, Target, When, WS};
 | 
					use parser::{self, Cond, Expr, Macro, MatchParameter, MatchVariant, Node, Target, When, WS};
 | 
				
			||||||
use shared::{filters, path};
 | 
					use shared::{filters, path};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use quote::ToTokens;
 | 
					 | 
				
			||||||
use proc_macro2::Span;
 | 
					use proc_macro2::Span;
 | 
				
			||||||
 | 
					use quote::ToTokens;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use std::{cmp, hash, str};
 | 
					 | 
				
			||||||
use std::path::Path;
 | 
					 | 
				
			||||||
use std::collections::{HashMap, HashSet};
 | 
					use std::collections::{HashMap, HashSet};
 | 
				
			||||||
 | 
					use std::path::Path;
 | 
				
			||||||
 | 
					use std::{cmp, hash, str};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use syn;
 | 
					use syn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn generate(input: &TemplateInput, nodes: &[Node]) -> String {
 | 
					pub fn generate(input: &TemplateInput, nodes: &[Node]) -> String {
 | 
				
			||||||
    let mut sources = HashMap::new();
 | 
					    let mut sources = HashMap::new();
 | 
				
			||||||
    let mut parsed = HashMap::new();
 | 
					    let mut parsed = HashMap::new();
 | 
				
			||||||
@ -26,20 +25,20 @@ pub fn generate(input: &TemplateInput, nodes: &[Node]) -> String {
 | 
				
			|||||||
                Some(_) => panic!("multiple extend blocks found"),
 | 
					                Some(_) => panic!("multiple extend blocks found"),
 | 
				
			||||||
                None => {
 | 
					                None => {
 | 
				
			||||||
                    base = Some(*path);
 | 
					                    base = Some(*path);
 | 
				
			||||||
                },
 | 
					                }
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            def @ Node::BlockDef(_, _, _, _) => {
 | 
					            def @ Node::BlockDef(_, _, _, _) => {
 | 
				
			||||||
                blocks.push(def);
 | 
					                blocks.push(def);
 | 
				
			||||||
            },
 | 
					            }
 | 
				
			||||||
            Node::Macro(name, m) => {
 | 
					            Node::Macro(name, m) => {
 | 
				
			||||||
                macros.insert((None, *name), m);
 | 
					                macros.insert((None, *name), m);
 | 
				
			||||||
            },
 | 
					            }
 | 
				
			||||||
            Node::Import(_, import_path, scope) => {
 | 
					            Node::Import(_, import_path, scope) => {
 | 
				
			||||||
                let path = path::find_template_from_path(import_path, Some(&input.path));
 | 
					                let path = path::find_template_from_path(import_path, Some(&input.path));
 | 
				
			||||||
                sources.insert(path.clone(), path::get_template_source(&path));
 | 
					                sources.insert(path.clone(), path::get_template_source(&path));
 | 
				
			||||||
                imported.push((*scope, path));
 | 
					                imported.push((*scope, path));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            _ => {},
 | 
					            _ => {}
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    for (path, src) in &sources {
 | 
					    for (path, src) in &sources {
 | 
				
			||||||
@ -77,9 +76,9 @@ pub fn generate(input: &TemplateInput, nodes: &[Node]) -> String {
 | 
				
			|||||||
        blocks: &blocks,
 | 
					        blocks: &blocks,
 | 
				
			||||||
        macros: ¯os,
 | 
					        macros: ¯os,
 | 
				
			||||||
        trait_name: match base {
 | 
					        trait_name: match base {
 | 
				
			||||||
            Some(user_path) => trait_name_for_path(
 | 
					            Some(user_path) => {
 | 
				
			||||||
                &path::find_template_from_path(user_path, Some(&input.path))
 | 
					                trait_name_for_path(&path::find_template_from_path(user_path, Some(&input.path)))
 | 
				
			||||||
            ),
 | 
					            }
 | 
				
			||||||
            None => trait_name_for_path(&input.path),
 | 
					            None => trait_name_for_path(&input.path),
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        derived: base.is_some(),
 | 
					        derived: base.is_some(),
 | 
				
			||||||
@ -176,8 +175,10 @@ impl<'a> Generator<'a> {
 | 
				
			|||||||
    // Implement `Template` for the given context struct.
 | 
					    // Implement `Template` for the given context struct.
 | 
				
			||||||
    fn impl_template(&mut self, state: &'a State) {
 | 
					    fn impl_template(&mut self, state: &'a State) {
 | 
				
			||||||
        self.write_header(state, "::askama::Template", None);
 | 
					        self.write_header(state, "::askama::Template", None);
 | 
				
			||||||
        self.writeln("fn render_into(&self, writer: &mut ::std::fmt::Write) -> \
 | 
					        self.writeln(
 | 
				
			||||||
                      ::askama::Result<()> {");
 | 
					            "fn render_into(&self, writer: &mut ::std::fmt::Write) -> \
 | 
				
			||||||
 | 
					             ::askama::Result<()> {",
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
        self.handle(state, state.nodes, AstLevel::Top);
 | 
					        self.handle(state, state.nodes, AstLevel::Top);
 | 
				
			||||||
        self.flush_ws(&WS(false, false));
 | 
					        self.flush_ws(&WS(false, false));
 | 
				
			||||||
        self.writeln("Ok(())");
 | 
					        self.writeln("Ok(())");
 | 
				
			||||||
@ -197,7 +198,10 @@ impl<'a> Generator<'a> {
 | 
				
			|||||||
    // Implement `Deref<Parent>` for an inheriting context struct.
 | 
					    // Implement `Deref<Parent>` for an inheriting context struct.
 | 
				
			||||||
    fn deref_to_parent(&mut self, state: &'a State, parent_type: &syn::Type) {
 | 
					    fn deref_to_parent(&mut self, state: &'a State, parent_type: &syn::Type) {
 | 
				
			||||||
        self.write_header(state, "::std::ops::Deref", None);
 | 
					        self.write_header(state, "::std::ops::Deref", None);
 | 
				
			||||||
        self.writeln(&format!("type Target = {};", parent_type.into_token_stream()));
 | 
					        self.writeln(&format!(
 | 
				
			||||||
 | 
					            "type Target = {};",
 | 
				
			||||||
 | 
					            parent_type.into_token_stream()
 | 
				
			||||||
 | 
					        ));
 | 
				
			||||||
        self.writeln("fn deref(&self) -> &Self::Target {");
 | 
					        self.writeln("fn deref(&self) -> &Self::Target {");
 | 
				
			||||||
        self.writeln("&self._parent");
 | 
					        self.writeln("&self._parent");
 | 
				
			||||||
        self.writeln("}");
 | 
					        self.writeln("}");
 | 
				
			||||||
@ -234,8 +238,10 @@ impl<'a> Generator<'a> {
 | 
				
			|||||||
    // Implement `Template` for templates that implement a template trait.
 | 
					    // Implement `Template` for templates that implement a template trait.
 | 
				
			||||||
    fn impl_template_for_trait(&mut self, state: &'a State) {
 | 
					    fn impl_template_for_trait(&mut self, state: &'a State) {
 | 
				
			||||||
        self.write_header(state, "::askama::Template", None);
 | 
					        self.write_header(state, "::askama::Template", None);
 | 
				
			||||||
        self.writeln("fn render_into(&self, writer: &mut ::std::fmt::Write) \
 | 
					        self.writeln(
 | 
				
			||||||
                      -> ::askama::Result<()> {");
 | 
					            "fn render_into(&self, writer: &mut ::std::fmt::Write) \
 | 
				
			||||||
 | 
					             -> ::askama::Result<()> {",
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
        if state.derived {
 | 
					        if state.derived {
 | 
				
			||||||
            self.writeln("self._parent.render_trait_into(self, writer)");
 | 
					            self.writeln("self._parent.render_trait_into(self, writer)");
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
@ -252,21 +258,30 @@ impl<'a> Generator<'a> {
 | 
				
			|||||||
        self.writeln(&format!(
 | 
					        self.writeln(&format!(
 | 
				
			||||||
            "fn render_trait_into(&self, timpl: &{}, writer: &mut ::std::fmt::Write) \
 | 
					            "fn render_trait_into(&self, timpl: &{}, writer: &mut ::std::fmt::Write) \
 | 
				
			||||||
             -> ::askama::Result<()>;",
 | 
					             -> ::askama::Result<()>;",
 | 
				
			||||||
            state.trait_name));
 | 
					            state.trait_name
 | 
				
			||||||
 | 
					        ));
 | 
				
			||||||
        self.writeln("}");
 | 
					        self.writeln("}");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Implement iron's Modifier<Response> if enabled
 | 
					    // Implement iron's Modifier<Response> if enabled
 | 
				
			||||||
    fn impl_modifier_response(&mut self, state: &'a State) {
 | 
					    fn impl_modifier_response(&mut self, state: &'a State) {
 | 
				
			||||||
        self.write_header(state, "::askama::iron::Modifier<::askama::iron::Response>", None);
 | 
					        self.write_header(
 | 
				
			||||||
 | 
					            state,
 | 
				
			||||||
 | 
					            "::askama::iron::Modifier<::askama::iron::Response>",
 | 
				
			||||||
 | 
					            None,
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
        self.writeln("fn modify(self, res: &mut ::askama::iron::Response) {");
 | 
					        self.writeln("fn modify(self, res: &mut ::askama::iron::Response) {");
 | 
				
			||||||
        self.writeln("res.body = Some(Box::new(self.render().unwrap().into_bytes()));");
 | 
					        self.writeln("res.body = Some(Box::new(self.render().unwrap().into_bytes()));");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let ext = state.input.path.extension().map_or("", |s| s.to_str().unwrap_or(""));
 | 
					        let ext = state
 | 
				
			||||||
 | 
					            .input
 | 
				
			||||||
 | 
					            .path
 | 
				
			||||||
 | 
					            .extension()
 | 
				
			||||||
 | 
					            .map_or("", |s| s.to_str().unwrap_or(""));
 | 
				
			||||||
        match ext {
 | 
					        match ext {
 | 
				
			||||||
            "html" | "htm" => {
 | 
					            "html" | "htm" => {
 | 
				
			||||||
                self.writeln("::askama::iron::ContentType::html().0.modify(res);");
 | 
					                self.writeln("::askama::iron::ContentType::html().0.modify(res);");
 | 
				
			||||||
            },
 | 
					            }
 | 
				
			||||||
            _ => (),
 | 
					            _ => (),
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -278,9 +293,15 @@ impl<'a> Generator<'a> {
 | 
				
			|||||||
    fn impl_responder(&mut self, state: &'a State) {
 | 
					    fn impl_responder(&mut self, state: &'a State) {
 | 
				
			||||||
        let lifetime = syn::Lifetime::new("'askama", Span::call_site());
 | 
					        let lifetime = syn::Lifetime::new("'askama", Span::call_site());
 | 
				
			||||||
        let param = syn::GenericParam::Lifetime(syn::LifetimeDef::new(lifetime));
 | 
					        let param = syn::GenericParam::Lifetime(syn::LifetimeDef::new(lifetime));
 | 
				
			||||||
        self.write_header(state, "::askama::rocket::Responder<'askama>", Some(vec![param]));
 | 
					        self.write_header(
 | 
				
			||||||
        self.writeln("fn respond_to(self, _: &::askama::rocket::Request) \
 | 
					            state,
 | 
				
			||||||
                      -> ::askama::rocket::Result<'askama> {");
 | 
					            "::askama::rocket::Responder<'askama>",
 | 
				
			||||||
 | 
					            Some(vec![param]),
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        self.writeln(
 | 
				
			||||||
 | 
					            "fn respond_to(self, _: &::askama::rocket::Request) \
 | 
				
			||||||
 | 
					             -> ::askama::rocket::Result<'askama> {",
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let ext = match state.input.path.extension() {
 | 
					        let ext = match state.input.path.extension() {
 | 
				
			||||||
            Some(s) => s.to_str().unwrap(),
 | 
					            Some(s) => s.to_str().unwrap(),
 | 
				
			||||||
@ -294,8 +315,12 @@ impl<'a> Generator<'a> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Writes header for the `impl` for `TraitFromPathName` or `Template`
 | 
					    // Writes header for the `impl` for `TraitFromPathName` or `Template`
 | 
				
			||||||
    // for the given context struct.
 | 
					    // for the given context struct.
 | 
				
			||||||
    fn write_header(&mut self, state: &'a State, target: &str,
 | 
					    fn write_header(
 | 
				
			||||||
                    params: Option<Vec<syn::GenericParam>>) {
 | 
					        &mut self,
 | 
				
			||||||
 | 
					        state: &'a State,
 | 
				
			||||||
 | 
					        target: &str,
 | 
				
			||||||
 | 
					        params: Option<Vec<syn::GenericParam>>,
 | 
				
			||||||
 | 
					    ) {
 | 
				
			||||||
        let mut generics = state.input.ast.generics.clone();
 | 
					        let mut generics = state.input.ast.generics.clone();
 | 
				
			||||||
        if let Some(params) = params {
 | 
					        if let Some(params) = params {
 | 
				
			||||||
            for param in params {
 | 
					            for param in params {
 | 
				
			||||||
@ -322,61 +347,64 @@ impl<'a> Generator<'a> {
 | 
				
			|||||||
            match *n {
 | 
					            match *n {
 | 
				
			||||||
                Node::Lit(lws, val, rws) => {
 | 
					                Node::Lit(lws, val, rws) => {
 | 
				
			||||||
                    self.write_lit(lws, val, rws);
 | 
					                    self.write_lit(lws, val, rws);
 | 
				
			||||||
                },
 | 
					                }
 | 
				
			||||||
                Node::Comment(ref ws) => {
 | 
					                Node::Comment(ref ws) => {
 | 
				
			||||||
                    self.write_comment(ws);
 | 
					                    self.write_comment(ws);
 | 
				
			||||||
                },
 | 
					                }
 | 
				
			||||||
                Node::Expr(ref ws, ref val) => {
 | 
					                Node::Expr(ref ws, ref val) => {
 | 
				
			||||||
                    self.write_expr(state, ws, val);
 | 
					                    self.write_expr(state, ws, val);
 | 
				
			||||||
                },
 | 
					                }
 | 
				
			||||||
                Node::LetDecl(ref ws, ref var) => {
 | 
					                Node::LetDecl(ref ws, ref var) => {
 | 
				
			||||||
                    self.write_let_decl(ws, var);
 | 
					                    self.write_let_decl(ws, var);
 | 
				
			||||||
                },
 | 
					                }
 | 
				
			||||||
                Node::Let(ref ws, ref var, ref val) => {
 | 
					                Node::Let(ref ws, ref var, ref val) => {
 | 
				
			||||||
                    self.write_let(ws, var, val);
 | 
					                    self.write_let(ws, var, val);
 | 
				
			||||||
                },
 | 
					                }
 | 
				
			||||||
                Node::Cond(ref conds, ref ws) => {
 | 
					                Node::Cond(ref conds, ref ws) => {
 | 
				
			||||||
                    self.write_cond(state, conds, ws);
 | 
					                    self.write_cond(state, conds, ws);
 | 
				
			||||||
                },
 | 
					                }
 | 
				
			||||||
                Node::Match(ref ws1, ref expr, inter, ref arms, ref ws2) => {
 | 
					                Node::Match(ref ws1, ref expr, inter, ref arms, ref ws2) => {
 | 
				
			||||||
                    self.write_match(state, ws1, expr, inter, arms, ws2);
 | 
					                    self.write_match(state, ws1, expr, inter, arms, ws2);
 | 
				
			||||||
                },
 | 
					                }
 | 
				
			||||||
                Node::Loop(ref ws1, ref var, ref iter, ref body, ref ws2) => {
 | 
					                Node::Loop(ref ws1, ref var, ref iter, ref body, ref ws2) => {
 | 
				
			||||||
                    self.write_loop(state, ws1, var, iter, body, ws2);
 | 
					                    self.write_loop(state, ws1, var, iter, body, ws2);
 | 
				
			||||||
                },
 | 
					                }
 | 
				
			||||||
                Node::BlockDef(ref ws1, name, _, ref ws2) => {
 | 
					                Node::BlockDef(ref ws1, name, _, ref ws2) => {
 | 
				
			||||||
                    if let AstLevel::Nested = level {
 | 
					                    if let AstLevel::Nested = level {
 | 
				
			||||||
                        panic!("blocks ('{}') are only allowed at the top level of a template \
 | 
					                        panic!(
 | 
				
			||||||
                                or another block", name);
 | 
					                            "blocks ('{}') are only allowed at the top level of a template \
 | 
				
			||||||
 | 
					                             or another block",
 | 
				
			||||||
 | 
					                            name
 | 
				
			||||||
 | 
					                        );
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    self.write_block(ws1, name, ws2);
 | 
					                    self.write_block(ws1, name, ws2);
 | 
				
			||||||
                },
 | 
					                }
 | 
				
			||||||
                Node::Include(ref ws, path) => {
 | 
					                Node::Include(ref ws, path) => {
 | 
				
			||||||
                    self.handle_include(state, ws, path);
 | 
					                    self.handle_include(state, ws, path);
 | 
				
			||||||
                },
 | 
					                }
 | 
				
			||||||
                Node::Call(ref ws, scope, name, ref args) => {
 | 
					                Node::Call(ref ws, scope, name, ref args) => {
 | 
				
			||||||
                    self.write_call(state, ws, scope, name, args);
 | 
					                    self.write_call(state, ws, scope, name, args);
 | 
				
			||||||
                },
 | 
					                }
 | 
				
			||||||
                Node::Macro(_, ref m) => {
 | 
					                Node::Macro(_, ref m) => {
 | 
				
			||||||
                    if level != AstLevel::Top {
 | 
					                    if level != AstLevel::Top {
 | 
				
			||||||
                        panic!("macro blocks only allowed at the top level");
 | 
					                        panic!("macro blocks only allowed at the top level");
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    self.flush_ws(&m.ws1);
 | 
					                    self.flush_ws(&m.ws1);
 | 
				
			||||||
                    self.prepare_ws(&m.ws2);
 | 
					                    self.prepare_ws(&m.ws2);
 | 
				
			||||||
                },
 | 
					                }
 | 
				
			||||||
                Node::Import(ref ws, _, _) => {
 | 
					                Node::Import(ref ws, _, _) => {
 | 
				
			||||||
                    if level != AstLevel::Top {
 | 
					                    if level != AstLevel::Top {
 | 
				
			||||||
                        panic!("import blocks only allowed at the top level");
 | 
					                        panic!("import blocks only allowed at the top level");
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    self.handle_ws(ws);
 | 
					                    self.handle_ws(ws);
 | 
				
			||||||
                },
 | 
					                }
 | 
				
			||||||
                Node::Extends(_) => {
 | 
					                Node::Extends(_) => {
 | 
				
			||||||
                    if level != AstLevel::Top {
 | 
					                    if level != AstLevel::Top {
 | 
				
			||||||
                        panic!("extend blocks only allowed at the top level");
 | 
					                        panic!("extend blocks only allowed at the top level");
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    // No whitespace handling: child template top-level is not used,
 | 
					                    // No whitespace handling: child template top-level is not used,
 | 
				
			||||||
                    // except for the blocks defined in it.
 | 
					                    // except for the blocks defined in it.
 | 
				
			||||||
                },
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -418,11 +446,11 @@ impl<'a> Generator<'a> {
 | 
				
			|||||||
                        self.write("} else if ");
 | 
					                        self.write("} else if ");
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    self.write(&expr_code);
 | 
					                    self.write(&expr_code);
 | 
				
			||||||
                },
 | 
					                }
 | 
				
			||||||
                None => {
 | 
					                None => {
 | 
				
			||||||
                    self.dedent();
 | 
					                    self.dedent();
 | 
				
			||||||
                    self.write("} else");
 | 
					                    self.write("} else");
 | 
				
			||||||
                },
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            self.writeln(" {");
 | 
					            self.writeln(" {");
 | 
				
			||||||
            self.locals.push();
 | 
					            self.locals.push();
 | 
				
			||||||
@ -433,8 +461,15 @@ impl<'a> Generator<'a> {
 | 
				
			|||||||
        self.writeln("}");
 | 
					        self.writeln("}");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn write_match(&mut self, state: &'a State, ws1: &WS, expr: &Expr, inter: Option<&'a str>,
 | 
					    fn write_match(
 | 
				
			||||||
                   arms: &'a [When], ws2: &WS) {
 | 
					        &mut self,
 | 
				
			||||||
 | 
					        state: &'a State,
 | 
				
			||||||
 | 
					        ws1: &WS,
 | 
				
			||||||
 | 
					        expr: &Expr,
 | 
				
			||||||
 | 
					        inter: Option<&'a str>,
 | 
				
			||||||
 | 
					        arms: &'a [When],
 | 
				
			||||||
 | 
					        ws2: &WS,
 | 
				
			||||||
 | 
					    ) {
 | 
				
			||||||
        self.flush_ws(ws1);
 | 
					        self.flush_ws(ws1);
 | 
				
			||||||
        if let Some(inter) = inter {
 | 
					        if let Some(inter) = inter {
 | 
				
			||||||
            if !inter.is_empty() {
 | 
					            if !inter.is_empty() {
 | 
				
			||||||
@ -450,7 +485,7 @@ impl<'a> Generator<'a> {
 | 
				
			|||||||
            match *variant {
 | 
					            match *variant {
 | 
				
			||||||
                Some(ref param) => {
 | 
					                Some(ref param) => {
 | 
				
			||||||
                    self.visit_match_variant(param);
 | 
					                    self.visit_match_variant(param);
 | 
				
			||||||
                },
 | 
					                }
 | 
				
			||||||
                None => self.write("_"),
 | 
					                None => self.write("_"),
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
            if !params.is_empty() {
 | 
					            if !params.is_empty() {
 | 
				
			||||||
@ -477,8 +512,15 @@ impl<'a> Generator<'a> {
 | 
				
			|||||||
        self.handle_ws(ws2);
 | 
					        self.handle_ws(ws2);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn write_loop(&mut self, state: &'a State, ws1: &WS, var: &'a Target, iter: &Expr,
 | 
					    fn write_loop(
 | 
				
			||||||
                  body: &'a [Node], ws2: &WS) {
 | 
					        &mut self,
 | 
				
			||||||
 | 
					        state: &'a State,
 | 
				
			||||||
 | 
					        ws1: &WS,
 | 
				
			||||||
 | 
					        var: &'a Target,
 | 
				
			||||||
 | 
					        iter: &Expr,
 | 
				
			||||||
 | 
					        body: &'a [Node],
 | 
				
			||||||
 | 
					        ws2: &WS,
 | 
				
			||||||
 | 
					    ) {
 | 
				
			||||||
        self.handle_ws(ws1);
 | 
					        self.handle_ws(ws1);
 | 
				
			||||||
        self.locals.push();
 | 
					        self.locals.push();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -497,8 +539,14 @@ impl<'a> Generator<'a> {
 | 
				
			|||||||
        self.locals.pop();
 | 
					        self.locals.pop();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn write_call(&mut self, state: &'a State, ws: &WS, scope: Option<&str>, name: &str,
 | 
					    fn write_call(
 | 
				
			||||||
                  args: &[Expr]) {
 | 
					        &mut self,
 | 
				
			||||||
 | 
					        state: &'a State,
 | 
				
			||||||
 | 
					        ws: &WS,
 | 
				
			||||||
 | 
					        scope: Option<&str>,
 | 
				
			||||||
 | 
					        name: &str,
 | 
				
			||||||
 | 
					        args: &[Expr],
 | 
				
			||||||
 | 
					    ) {
 | 
				
			||||||
        let def = state.macros.get(&(scope, name)).unwrap_or_else(|| {
 | 
					        let def = state.macros.get(&(scope, name)).unwrap_or_else(|| {
 | 
				
			||||||
            if let Some(s) = scope {
 | 
					            if let Some(s) = scope {
 | 
				
			||||||
                panic!(format!("macro '{}::{}' not found", s, name));
 | 
					                panic!(format!("macro '{}::{}' not found", s, name));
 | 
				
			||||||
@ -513,8 +561,10 @@ impl<'a> Generator<'a> {
 | 
				
			|||||||
        self.prepare_ws(&def.ws1);
 | 
					        self.prepare_ws(&def.ws1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (i, arg) in def.args.iter().enumerate() {
 | 
					        for (i, arg) in def.args.iter().enumerate() {
 | 
				
			||||||
            let expr_code = self.visit_expr_root(args.get(i)
 | 
					            let expr_code = self.visit_expr_root(
 | 
				
			||||||
                .expect(&format!("macro '{}' takes more than {} arguments", name, i)));
 | 
					                args.get(i)
 | 
				
			||||||
 | 
					                    .expect(&format!("macro '{}' takes more than {} arguments", name, i)),
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
            self.write(&format!("let {} = &{};", arg, expr_code));
 | 
					            self.write(&format!("let {} = &{};", arg, expr_code));
 | 
				
			||||||
            self.locals.insert(arg);
 | 
					            self.locals.insert(arg);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -547,7 +597,7 @@ impl<'a> Generator<'a> {
 | 
				
			|||||||
            Target::Name(name) => {
 | 
					            Target::Name(name) => {
 | 
				
			||||||
                self.locals.insert(name);
 | 
					                self.locals.insert(name);
 | 
				
			||||||
                self.write(name);
 | 
					                self.write(name);
 | 
				
			||||||
            },
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        self.writeln(";");
 | 
					        self.writeln(";");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -564,18 +614,14 @@ impl<'a> Generator<'a> {
 | 
				
			|||||||
                    self.locals.insert(name);
 | 
					                    self.locals.insert(name);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                self.write(name);
 | 
					                self.write(name);
 | 
				
			||||||
            },
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        self.write(&format!(" = {};", &code));
 | 
					        self.write(&format!(" = {};", &code));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn write_block(&mut self, ws1: &WS, name: &str, ws2: &WS) {
 | 
					    fn write_block(&mut self, ws1: &WS, name: &str, ws2: &WS) {
 | 
				
			||||||
        self.flush_ws(ws1);
 | 
					        self.flush_ws(ws1);
 | 
				
			||||||
        let ctx = if self.impl_blocks {
 | 
					        let ctx = if self.impl_blocks { "timpl" } else { "self" };
 | 
				
			||||||
            "timpl"
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            "self"
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        self.writeln(&format!("{}.render_block_{}_into(writer)?;", ctx, name));
 | 
					        self.writeln(&format!("{}.render_block_{}_into(writer)?;", ctx, name));
 | 
				
			||||||
        self.prepare_ws(ws2);
 | 
					        self.prepare_ws(ws2);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -590,9 +636,7 @@ impl<'a> Generator<'a> {
 | 
				
			|||||||
        use super::input::EscapeMode::*;
 | 
					        use super::input::EscapeMode::*;
 | 
				
			||||||
        self.write("writer.write_fmt(format_args!(\"{}\", ");
 | 
					        self.write("writer.write_fmt(format_args!(\"{}\", ");
 | 
				
			||||||
        self.write(match (wrapped, &state.input.escaping) {
 | 
					        self.write(match (wrapped, &state.input.escaping) {
 | 
				
			||||||
            (Wrapped, &Html) |
 | 
					            (Wrapped, &Html) | (Wrapped, &None) | (Unwrapped, &None) => "askama_expr",
 | 
				
			||||||
            (Wrapped, &None) |
 | 
					 | 
				
			||||||
            (Unwrapped, &None) => "askama_expr",
 | 
					 | 
				
			||||||
            (Unwrapped, &Html) => "&::askama::MarkupDisplay::from(askama_expr)",
 | 
					            (Unwrapped, &Html) => "&::askama::MarkupDisplay::from(askama_expr)",
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        self.writeln("))?;");
 | 
					        self.writeln("))?;");
 | 
				
			||||||
@ -644,7 +688,7 @@ impl<'a> Generator<'a> {
 | 
				
			|||||||
            Expr::Group(ref inner) => self.visit_group(inner, code),
 | 
					            Expr::Group(ref inner) => self.visit_group(inner, code),
 | 
				
			||||||
            Expr::MethodCall(ref obj, method, ref args) => {
 | 
					            Expr::MethodCall(ref obj, method, ref args) => {
 | 
				
			||||||
                self.visit_method_call(obj, method, args, code)
 | 
					                self.visit_method_call(obj, method, args, code)
 | 
				
			||||||
            },
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -659,11 +703,11 @@ impl<'a> Generator<'a> {
 | 
				
			|||||||
            MatchVariant::Name(s) => {
 | 
					            MatchVariant::Name(s) => {
 | 
				
			||||||
                code.push_str(s);
 | 
					                code.push_str(s);
 | 
				
			||||||
                DisplayWrap::Unwrapped
 | 
					                DisplayWrap::Unwrapped
 | 
				
			||||||
            },
 | 
					            }
 | 
				
			||||||
            MatchVariant::Path(ref s) => {
 | 
					            MatchVariant::Path(ref s) => {
 | 
				
			||||||
                code.push_str(&s.join("::"));
 | 
					                code.push_str(&s.join("::"));
 | 
				
			||||||
                DisplayWrap::Unwrapped
 | 
					                DisplayWrap::Unwrapped
 | 
				
			||||||
            },
 | 
					            }
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        self.write(&code);
 | 
					        self.write(&code);
 | 
				
			||||||
        wrapped
 | 
					        wrapped
 | 
				
			||||||
@ -677,7 +721,7 @@ impl<'a> Generator<'a> {
 | 
				
			|||||||
            MatchParameter::Name(s) => {
 | 
					            MatchParameter::Name(s) => {
 | 
				
			||||||
                code.push_str(s);
 | 
					                code.push_str(s);
 | 
				
			||||||
                DisplayWrap::Unwrapped
 | 
					                DisplayWrap::Unwrapped
 | 
				
			||||||
            },
 | 
					            }
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        self.write(&code);
 | 
					        self.write(&code);
 | 
				
			||||||
        wrapped
 | 
					        wrapped
 | 
				
			||||||
@ -772,8 +816,13 @@ impl<'a> Generator<'a> {
 | 
				
			|||||||
        DisplayWrap::Unwrapped
 | 
					        DisplayWrap::Unwrapped
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn visit_method_call(&mut self, obj: &Expr, method: &str, args: &[Expr], code: &mut String)
 | 
					    fn visit_method_call(
 | 
				
			||||||
                         -> DisplayWrap {
 | 
					        &mut self,
 | 
				
			||||||
 | 
					        obj: &Expr,
 | 
				
			||||||
 | 
					        method: &str,
 | 
				
			||||||
 | 
					        args: &[Expr],
 | 
				
			||||||
 | 
					        code: &mut String,
 | 
				
			||||||
 | 
					    ) -> DisplayWrap {
 | 
				
			||||||
        if let Expr::Var("self") = obj {
 | 
					        if let Expr::Var("self") = obj {
 | 
				
			||||||
            code.push_str("self");
 | 
					            code.push_str("self");
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
@ -792,8 +841,13 @@ impl<'a> Generator<'a> {
 | 
				
			|||||||
        DisplayWrap::Unwrapped
 | 
					        DisplayWrap::Unwrapped
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn visit_binop(&mut self, op: &str, left: &Expr, right: &Expr, code: &mut String)
 | 
					    fn visit_binop(
 | 
				
			||||||
                   -> DisplayWrap {
 | 
					        &mut self,
 | 
				
			||||||
 | 
					        op: &str,
 | 
				
			||||||
 | 
					        left: &Expr,
 | 
				
			||||||
 | 
					        right: &Expr,
 | 
				
			||||||
 | 
					        code: &mut String,
 | 
				
			||||||
 | 
					    ) -> DisplayWrap {
 | 
				
			||||||
        self.visit_expr(left, code);
 | 
					        self.visit_expr(left, code);
 | 
				
			||||||
        code.push_str(&format!(" {} ", op));
 | 
					        code.push_str(&format!(" {} ", op));
 | 
				
			||||||
        self.visit_expr(right, code);
 | 
					        self.visit_expr(right, code);
 | 
				
			||||||
@ -926,17 +980,29 @@ impl<'a> Generator<'a> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct SetChain<'a, T: 'a> where T: cmp::Eq + hash::Hash {
 | 
					struct SetChain<'a, T: 'a>
 | 
				
			||||||
 | 
					where
 | 
				
			||||||
 | 
					    T: cmp::Eq + hash::Hash,
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    parent: Option<&'a SetChain<'a, T>>,
 | 
					    parent: Option<&'a SetChain<'a, T>>,
 | 
				
			||||||
    scopes: Vec<HashSet<T>>,
 | 
					    scopes: Vec<HashSet<T>>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'a, T: 'a> SetChain<'a, T> where T: cmp::Eq + hash::Hash {
 | 
					impl<'a, T: 'a> SetChain<'a, T>
 | 
				
			||||||
 | 
					where
 | 
				
			||||||
 | 
					    T: cmp::Eq + hash::Hash,
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    fn new() -> SetChain<'a, T> {
 | 
					    fn new() -> SetChain<'a, T> {
 | 
				
			||||||
        SetChain { parent: None, scopes: vec![HashSet::new()] }
 | 
					        SetChain {
 | 
				
			||||||
 | 
					            parent: None,
 | 
				
			||||||
 | 
					            scopes: vec![HashSet::new()],
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    fn with_parent<'p>(parent: &'p SetChain<T>) -> SetChain<'p, T> {
 | 
					    fn with_parent<'p>(parent: &'p SetChain<T>) -> SetChain<'p, T> {
 | 
				
			||||||
        SetChain { parent: Some(parent), scopes: vec![HashSet::new()] }
 | 
					        SetChain {
 | 
				
			||||||
 | 
					            parent: Some(parent),
 | 
				
			||||||
 | 
					            scopes: vec![HashSet::new()],
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    fn contains(&self, val: T) -> bool {
 | 
					    fn contains(&self, val: T) -> bool {
 | 
				
			||||||
        self.scopes.iter().rev().any(|set| set.contains(&val)) || match self.parent {
 | 
					        self.scopes.iter().rev().any(|set| set.contains(&val)) || match self.parent {
 | 
				
			||||||
@ -962,13 +1028,9 @@ fn get_parent_type(ast: &syn::DeriveInput) -> Option<&syn::Type> {
 | 
				
			|||||||
            fields: syn::Fields::Named(ref fields),
 | 
					            fields: syn::Fields::Named(ref fields),
 | 
				
			||||||
            ..
 | 
					            ..
 | 
				
			||||||
        }) => fields.named.iter().filter_map(|f| {
 | 
					        }) => fields.named.iter().filter_map(|f| {
 | 
				
			||||||
            f.ident.as_ref().and_then(|name| {
 | 
					            f.ident
 | 
				
			||||||
                if name == "_parent" {
 | 
					                .as_ref()
 | 
				
			||||||
                    Some(&f.ty)
 | 
					                .and_then(|name| if name == "_parent" { Some(&f.ty) } else { None })
 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    None
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
        }),
 | 
					        }),
 | 
				
			||||||
        _ => panic!("derive(Template) only works for struct items"),
 | 
					        _ => panic!("derive(Template) only works for struct items"),
 | 
				
			||||||
    }.next()
 | 
					    }.next()
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,6 @@ use std::path::{Path, PathBuf};
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use syn;
 | 
					use syn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
pub struct TemplateInput<'a> {
 | 
					pub struct TemplateInput<'a> {
 | 
				
			||||||
    pub ast: &'a syn::DeriveInput,
 | 
					    pub ast: &'a syn::DeriveInput,
 | 
				
			||||||
    pub source: Source,
 | 
					    pub source: Source,
 | 
				
			||||||
@ -20,7 +19,10 @@ impl<'a> TemplateInput<'a> {
 | 
				
			|||||||
            .iter()
 | 
					            .iter()
 | 
				
			||||||
            .find(|a| a.interpret_meta().unwrap().name() == "template");
 | 
					            .find(|a| a.interpret_meta().unwrap().name() == "template");
 | 
				
			||||||
        if attr.is_none() {
 | 
					        if attr.is_none() {
 | 
				
			||||||
            panic!(format!("'template' attribute not found on struct '{}'", ast.ident));
 | 
					            panic!(format!(
 | 
				
			||||||
 | 
					                "'template' attribute not found on struct '{}'",
 | 
				
			||||||
 | 
					                ast.ident
 | 
				
			||||||
 | 
					            ));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let attr = attr.unwrap();
 | 
					        let attr = attr.unwrap();
 | 
				
			||||||
@ -75,18 +77,20 @@ impl<'a> TemplateInput<'a> {
 | 
				
			|||||||
        match (&source, ext.is_some()) {
 | 
					        match (&source, ext.is_some()) {
 | 
				
			||||||
            (&Source::Path(_), true) => {
 | 
					            (&Source::Path(_), true) => {
 | 
				
			||||||
                panic!("'ext' attribute cannot be used with 'path' attribute")
 | 
					                panic!("'ext' attribute cannot be used with 'path' attribute")
 | 
				
			||||||
            },
 | 
					            }
 | 
				
			||||||
            (&Source::Source(_), false) => {
 | 
					            (&Source::Source(_), false) => {
 | 
				
			||||||
                panic!("must include 'ext' attribute when using 'source' attribute")
 | 
					                panic!("must include 'ext' attribute when using 'source' attribute")
 | 
				
			||||||
            },
 | 
					            }
 | 
				
			||||||
            _ => {},
 | 
					            _ => {}
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        let escaping = match escaping {
 | 
					        let escaping = match escaping {
 | 
				
			||||||
            Some(m) => m,
 | 
					            Some(m) => m,
 | 
				
			||||||
            None => {
 | 
					            None => {
 | 
				
			||||||
                let ext = match source {
 | 
					                let ext = match source {
 | 
				
			||||||
                    Source::Path(ref p) =>
 | 
					                    Source::Path(ref p) => Path::new(p)
 | 
				
			||||||
                        Path::new(p).extension().map(|s| s.to_str().unwrap()).unwrap_or(""),
 | 
					                        .extension()
 | 
				
			||||||
 | 
					                        .map(|s| s.to_str().unwrap())
 | 
				
			||||||
 | 
					                        .unwrap_or(""),
 | 
				
			||||||
                    Source::Source(_) => ext.as_ref().unwrap(), // Already panicked if None
 | 
					                    Source::Source(_) => ext.as_ref().unwrap(), // Already panicked if None
 | 
				
			||||||
                };
 | 
					                };
 | 
				
			||||||
                if HTML_EXTENSIONS.contains(&ext) {
 | 
					                if HTML_EXTENSIONS.contains(&ext) {
 | 
				
			||||||
@ -94,7 +98,7 @@ impl<'a> TemplateInput<'a> {
 | 
				
			|||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    EscapeMode::None
 | 
					                    EscapeMode::None
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            },
 | 
					            }
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let path = match source {
 | 
					        let path = match source {
 | 
				
			||||||
 | 
				
			|||||||
@ -7,8 +7,8 @@ extern crate proc_macro2;
 | 
				
			|||||||
extern crate quote;
 | 
					extern crate quote;
 | 
				
			||||||
extern crate syn;
 | 
					extern crate syn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mod input;
 | 
					 | 
				
			||||||
mod generator;
 | 
					mod generator;
 | 
				
			||||||
 | 
					mod input;
 | 
				
			||||||
mod parser;
 | 
					mod parser;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use input::{Print, Source};
 | 
					use input::{Print, Source};
 | 
				
			||||||
@ -36,7 +36,7 @@ fn build_template(ast: &syn::DeriveInput) -> String {
 | 
				
			|||||||
    let input = input::TemplateInput::new(ast);
 | 
					    let input = input::TemplateInput::new(ast);
 | 
				
			||||||
    let source = match input.source {
 | 
					    let source = match input.source {
 | 
				
			||||||
        Source::Source(ref s) => s.clone(),
 | 
					        Source::Source(ref s) => s.clone(),
 | 
				
			||||||
        Source::Path(_) => path::get_template_source(&input.path)
 | 
					        Source::Path(_) => path::get_template_source(&input.path),
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let nodes = parser::parse(&source);
 | 
					    let nodes = parser::parse(&source);
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
 | 
					use std::error::Error as ErrorTrait;
 | 
				
			||||||
use std::fmt::{self, Display};
 | 
					use std::fmt::{self, Display};
 | 
				
			||||||
use std::error::{Error as ErrorTrait};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub type Result<I> = ::std::result::Result<I, Error>;
 | 
					pub type Result<I> = ::std::result::Result<I, Error>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -23,7 +23,7 @@ pub type Result<I> = ::std::result::Result<I, Error>;
 | 
				
			|||||||
/// bring to this crate are small, which is why
 | 
					/// bring to this crate are small, which is why
 | 
				
			||||||
/// `std::error::Error` was used.
 | 
					/// `std::error::Error` was used.
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
#[derive(Debug, )]
 | 
					#[derive(Debug)]
 | 
				
			||||||
pub enum Error {
 | 
					pub enum Error {
 | 
				
			||||||
    /// formatting error
 | 
					    /// formatting error
 | 
				
			||||||
    Fmt(fmt::Error),
 | 
					    Fmt(fmt::Error),
 | 
				
			||||||
@ -40,13 +40,12 @@ pub enum Error {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl ErrorTrait for Error {
 | 
					impl ErrorTrait for Error {
 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn description(&self) -> &str {
 | 
					    fn description(&self) -> &str {
 | 
				
			||||||
        match *self {
 | 
					        match *self {
 | 
				
			||||||
            Error::Fmt(ref err) => err.description(),
 | 
					            Error::Fmt(ref err) => err.description(),
 | 
				
			||||||
            #[cfg(feature = "serde-json")]
 | 
					            #[cfg(feature = "serde-json")]
 | 
				
			||||||
            Error::Json(ref err) => err.description(),
 | 
					            Error::Json(ref err) => err.description(),
 | 
				
			||||||
            _ => "unknown error: __Nonexhaustive"
 | 
					            _ => "unknown error: __Nonexhaustive",
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -55,7 +54,7 @@ impl ErrorTrait for Error {
 | 
				
			|||||||
            Error::Fmt(ref err) => err.cause(),
 | 
					            Error::Fmt(ref err) => err.cause(),
 | 
				
			||||||
            #[cfg(feature = "serde-json")]
 | 
					            #[cfg(feature = "serde-json")]
 | 
				
			||||||
            Error::Json(ref err) => err.cause(),
 | 
					            Error::Json(ref err) => err.cause(),
 | 
				
			||||||
            _ => None
 | 
					            _ => None,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -67,7 +66,7 @@ impl Display for Error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            #[cfg(feature = "serde-json")]
 | 
					            #[cfg(feature = "serde-json")]
 | 
				
			||||||
            Error::Json(ref err) => write!(formatter, "json conversion error: {}", err),
 | 
					            Error::Json(ref err) => write!(formatter, "json conversion error: {}", err),
 | 
				
			||||||
            _ => write!(formatter, "unknown error: __Nonexhaustive")
 | 
					            _ => write!(formatter, "unknown error: __Nonexhaustive"),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -85,7 +84,6 @@ impl From<::serde_json::Error> for Error {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(test)]
 | 
					#[cfg(test)]
 | 
				
			||||||
mod tests {
 | 
					mod tests {
 | 
				
			||||||
    use super::Error;
 | 
					    use super::Error;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,13 +1,18 @@
 | 
				
			|||||||
use std::fmt::{self, Display, Formatter};
 | 
					use std::fmt::{self, Display, Formatter};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Debug, PartialEq)]
 | 
					#[derive(Debug, PartialEq)]
 | 
				
			||||||
pub enum MarkupDisplay<T> where T: Display {
 | 
					pub enum MarkupDisplay<T>
 | 
				
			||||||
 | 
					where
 | 
				
			||||||
 | 
					    T: Display,
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    Safe(T),
 | 
					    Safe(T),
 | 
				
			||||||
    Unsafe(T),
 | 
					    Unsafe(T),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<T> MarkupDisplay<T> where T: Display {
 | 
					impl<T> MarkupDisplay<T>
 | 
				
			||||||
 | 
					where
 | 
				
			||||||
 | 
					    T: Display,
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    pub fn mark_safe(self) -> MarkupDisplay<T> {
 | 
					    pub fn mark_safe(self) -> MarkupDisplay<T> {
 | 
				
			||||||
        match self {
 | 
					        match self {
 | 
				
			||||||
            MarkupDisplay::Unsafe(t) => MarkupDisplay::Safe(t),
 | 
					            MarkupDisplay::Unsafe(t) => MarkupDisplay::Safe(t),
 | 
				
			||||||
@ -21,13 +26,19 @@ impl<T> MarkupDisplay<T> where T: Display {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<T> From<T> for MarkupDisplay<T> where T: Display {
 | 
					impl<T> From<T> for MarkupDisplay<T>
 | 
				
			||||||
 | 
					where
 | 
				
			||||||
 | 
					    T: Display,
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    fn from(t: T) -> MarkupDisplay<T> {
 | 
					    fn from(t: T) -> MarkupDisplay<T> {
 | 
				
			||||||
        MarkupDisplay::Unsafe(t)
 | 
					        MarkupDisplay::Unsafe(t)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<T> Display for MarkupDisplay<T> where T: Display {
 | 
					impl<T> Display for MarkupDisplay<T>
 | 
				
			||||||
 | 
					where
 | 
				
			||||||
 | 
					    T: Display,
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
 | 
					    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
 | 
				
			||||||
        match *self {
 | 
					        match *self {
 | 
				
			||||||
            MarkupDisplay::Unsafe(_) => write!(f, "{}", escape(self.unsafe_string())),
 | 
					            MarkupDisplay::Unsafe(_) => write!(f, "{}", escape(self.unsafe_string())),
 | 
				
			||||||
@ -36,7 +47,6 @@ impl<T> Display for MarkupDisplay<T> where T: Display {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
fn escapable(b: u8) -> bool {
 | 
					fn escapable(b: u8) -> bool {
 | 
				
			||||||
    match b {
 | 
					    match b {
 | 
				
			||||||
        b'<' | b'>' | b'&' | b'"' | b'\'' | b'/' => true,
 | 
					        b'<' | b'>' | b'&' | b'"' | b'\'' | b'/' => true,
 | 
				
			||||||
@ -65,12 +75,24 @@ pub fn escape(s: String) -> String {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        start = *idx + 1;
 | 
					        start = *idx + 1;
 | 
				
			||||||
        match bytes[*idx] {
 | 
					        match bytes[*idx] {
 | 
				
			||||||
            b'<' => { res.extend(b"<"); },
 | 
					            b'<' => {
 | 
				
			||||||
            b'>' => { res.extend(b">"); },
 | 
					                res.extend(b"<");
 | 
				
			||||||
            b'&' => { res.extend(b"&"); },
 | 
					            }
 | 
				
			||||||
            b'"' => { res.extend(b"""); },
 | 
					            b'>' => {
 | 
				
			||||||
            b'\'' => { res.extend(b"'"); },
 | 
					                res.extend(b">");
 | 
				
			||||||
            b'/' => { res.extend(b"/"); },
 | 
					            }
 | 
				
			||||||
 | 
					            b'&' => {
 | 
				
			||||||
 | 
					                res.extend(b"&");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            b'"' => {
 | 
				
			||||||
 | 
					                res.extend(b""");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            b'\'' => {
 | 
				
			||||||
 | 
					                res.extend(b"'");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            b'/' => {
 | 
				
			||||||
 | 
					                res.extend(b"/");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            _ => panic!("incorrect indexing"),
 | 
					            _ => panic!("incorrect indexing"),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -81,7 +103,6 @@ pub fn escape(s: String) -> String {
 | 
				
			|||||||
    String::from_utf8(res).unwrap()
 | 
					    String::from_utf8(res).unwrap()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(test)]
 | 
					#[cfg(test)]
 | 
				
			||||||
mod tests {
 | 
					mod tests {
 | 
				
			||||||
    use super::*;
 | 
					    use super::*;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,9 +1,8 @@
 | 
				
			|||||||
 | 
					use error::{Error, Result};
 | 
				
			||||||
use serde::Serialize;
 | 
					use serde::Serialize;
 | 
				
			||||||
use serde_json;
 | 
					use serde_json;
 | 
				
			||||||
use error::{Error, Result};
 | 
					 | 
				
			||||||
use MarkupDisplay;
 | 
					use MarkupDisplay;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Serialize to JSON (requires `serde-json` feature)
 | 
					/// Serialize to JSON (requires `serde-json` feature)
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// ## Errors
 | 
					/// ## Errors
 | 
				
			||||||
@ -17,7 +16,6 @@ pub fn json<S: Serialize>(s: &S) -> Result<MarkupDisplay<String>> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(test)]
 | 
					#[cfg(test)]
 | 
				
			||||||
mod tests {
 | 
					mod tests {
 | 
				
			||||||
    use super::*;
 | 
					    use super::*;
 | 
				
			||||||
 | 
				
			|||||||
@ -11,9 +11,8 @@ pub use self::json::json;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use std::fmt;
 | 
					use std::fmt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use escaping::{self, MarkupDisplay};
 | 
					 | 
				
			||||||
use super::Result;
 | 
					use super::Result;
 | 
				
			||||||
 | 
					use escaping::{self, MarkupDisplay};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// This is used by the code generator to decide whether a named filter is part of
 | 
					// This is used by the code generator to decide whether a named filter is part of
 | 
				
			||||||
// Askama or should refer to a local `filters` module. It should contain all the
 | 
					// Askama or should refer to a local `filters` module. It should contain all the
 | 
				
			||||||
@ -32,11 +31,10 @@ pub const BUILT_IN_FILTERS: [&str; 10] = [
 | 
				
			|||||||
    "json", // Optional feature; reserve the name anyway
 | 
					    "json", // Optional feature; reserve the name anyway
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn safe<D, I>(v: I) -> Result<MarkupDisplay<D>>
 | 
					pub fn safe<D, I>(v: I) -> Result<MarkupDisplay<D>>
 | 
				
			||||||
where
 | 
					where
 | 
				
			||||||
    D: fmt::Display,
 | 
					    D: fmt::Display,
 | 
				
			||||||
    MarkupDisplay<D>: From<I>
 | 
					    MarkupDisplay<D>: From<I>,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    let res: MarkupDisplay<D> = v.into();
 | 
					    let res: MarkupDisplay<D> = v.into();
 | 
				
			||||||
    Ok(res.mark_safe())
 | 
					    Ok(res.mark_safe())
 | 
				
			||||||
@ -46,7 +44,7 @@ where
 | 
				
			|||||||
pub fn escape<D, I>(i: I) -> Result<MarkupDisplay<String>>
 | 
					pub fn escape<D, I>(i: I) -> Result<MarkupDisplay<String>>
 | 
				
			||||||
where
 | 
					where
 | 
				
			||||||
    D: fmt::Display,
 | 
					    D: fmt::Display,
 | 
				
			||||||
    MarkupDisplay<D>: From<I>
 | 
					    MarkupDisplay<D>: From<I>,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    let md: MarkupDisplay<D> = i.into();
 | 
					    let md: MarkupDisplay<D> = i.into();
 | 
				
			||||||
    Ok(MarkupDisplay::Safe(escaping::escape(md.unsafe_string())))
 | 
					    Ok(MarkupDisplay::Safe(escaping::escape(md.unsafe_string())))
 | 
				
			||||||
@ -56,7 +54,7 @@ where
 | 
				
			|||||||
pub fn e<D, I>(i: I) -> Result<MarkupDisplay<String>>
 | 
					pub fn e<D, I>(i: I) -> Result<MarkupDisplay<String>>
 | 
				
			||||||
where
 | 
					where
 | 
				
			||||||
    D: fmt::Display,
 | 
					    D: fmt::Display,
 | 
				
			||||||
    MarkupDisplay<D>: From<I>
 | 
					    MarkupDisplay<D>: From<I>,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    escape(i)
 | 
					    escape(i)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -99,9 +97,10 @@ pub fn trim(s: &fmt::Display) -> Result<String> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/// Joins iterable into a string separated by provided argument
 | 
					/// Joins iterable into a string separated by provided argument
 | 
				
			||||||
pub fn join<T, I, S>(input: I, separator: S) -> Result<String>
 | 
					pub fn join<T, I, S>(input: I, separator: S) -> Result<String>
 | 
				
			||||||
    where T: fmt::Display,
 | 
					where
 | 
				
			||||||
 | 
					    T: fmt::Display,
 | 
				
			||||||
    I: Iterator<Item = T>,
 | 
					    I: Iterator<Item = T>,
 | 
				
			||||||
          S: AsRef<str>
 | 
					    S: AsRef<str>,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    let separator: &str = separator.as_ref();
 | 
					    let separator: &str = separator.as_ref();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -118,7 +117,6 @@ pub fn join<T, I, S>(input: I, separator: S) -> Result<String>
 | 
				
			|||||||
    Ok(rv)
 | 
					    Ok(rv)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(test)]
 | 
					#[cfg(test)]
 | 
				
			||||||
mod tests {
 | 
					mod tests {
 | 
				
			||||||
    use super::*;
 | 
					    use super::*;
 | 
				
			||||||
 | 
				
			|||||||
@ -5,8 +5,8 @@ extern crate serde;
 | 
				
			|||||||
#[cfg(feature = "serde-json")]
 | 
					#[cfg(feature = "serde-json")]
 | 
				
			||||||
extern crate serde_json;
 | 
					extern crate serde_json;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub use escaping::MarkupDisplay;
 | 
					 | 
				
			||||||
pub use error::{Error, Result};
 | 
					pub use error::{Error, Result};
 | 
				
			||||||
 | 
					pub use escaping::MarkupDisplay;
 | 
				
			||||||
mod error;
 | 
					mod error;
 | 
				
			||||||
pub mod filters;
 | 
					pub mod filters;
 | 
				
			||||||
pub mod path;
 | 
					pub mod path;
 | 
				
			||||||
 | 
				
			|||||||
@ -10,7 +10,7 @@ pub fn get_template_source(tpl_path: &Path) -> String {
 | 
				
			|||||||
        Err(_) => {
 | 
					        Err(_) => {
 | 
				
			||||||
            let msg = format!("unable to open template file '{}'", &path.to_str().unwrap());
 | 
					            let msg = format!("unable to open template file '{}'", &path.to_str().unwrap());
 | 
				
			||||||
            panic!(msg)
 | 
					            panic!(msg)
 | 
				
			||||||
        },
 | 
					        }
 | 
				
			||||||
        Ok(f) => f,
 | 
					        Ok(f) => f,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    let mut s = String::new();
 | 
					    let mut s = String::new();
 | 
				
			||||||
@ -38,7 +38,11 @@ pub fn find_template_from_path(path: &str, start_at: Option<&Path>) -> PathBuf {
 | 
				
			|||||||
    if fs_abs_path.exists() {
 | 
					    if fs_abs_path.exists() {
 | 
				
			||||||
        path.to_owned()
 | 
					        path.to_owned()
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        panic!(format!("template {:?} not found at {:?}", path.to_str().unwrap(), fs_abs_path));
 | 
					        panic!(format!(
 | 
				
			||||||
 | 
					            "template {:?} not found at {:?}",
 | 
				
			||||||
 | 
					            path.to_str().unwrap(),
 | 
				
			||||||
 | 
					            fs_abs_path
 | 
				
			||||||
 | 
					        ));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -50,8 +54,8 @@ pub fn template_dir() -> PathBuf {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[cfg(test)]
 | 
					#[cfg(test)]
 | 
				
			||||||
mod tests {
 | 
					mod tests {
 | 
				
			||||||
    use super::{find_template_from_path, get_template_source};
 | 
					 | 
				
			||||||
    use super::Path;
 | 
					    use super::Path;
 | 
				
			||||||
 | 
					    use super::{find_template_from_path, get_template_source};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[test]
 | 
					    #[test]
 | 
				
			||||||
    fn get_source() {
 | 
					    fn get_source() {
 | 
				
			||||||
 | 
				
			|||||||
@ -6,7 +6,6 @@ extern crate serde_json;
 | 
				
			|||||||
use askama::Template;
 | 
					use askama::Template;
 | 
				
			||||||
use serde_json::Value;
 | 
					use serde_json::Value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Template)]
 | 
					#[derive(Template)]
 | 
				
			||||||
#[template(path = "filters.html")]
 | 
					#[template(path = "filters.html")]
 | 
				
			||||||
struct TestTemplate {
 | 
					struct TestTemplate {
 | 
				
			||||||
@ -25,7 +24,6 @@ fn filter_escape() {
 | 
				
			|||||||
    );
 | 
					    );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Template)]
 | 
					#[derive(Template)]
 | 
				
			||||||
#[template(path = "format.html", escape = "none")]
 | 
					#[template(path = "format.html", escape = "none")]
 | 
				
			||||||
struct FormatTemplate<'a> {
 | 
					struct FormatTemplate<'a> {
 | 
				
			||||||
@ -38,7 +36,6 @@ fn filter_format() {
 | 
				
			|||||||
    assert_eq!(t.render().unwrap(), "\"formatted\"");
 | 
					    assert_eq!(t.render().unwrap(), "\"formatted\"");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Template)]
 | 
					#[derive(Template)]
 | 
				
			||||||
#[template(source = "{{ s|myfilter }}", ext = "txt")]
 | 
					#[template(source = "{{ s|myfilter }}", ext = "txt")]
 | 
				
			||||||
struct MyFilterTemplate<'a> {
 | 
					struct MyFilterTemplate<'a> {
 | 
				
			||||||
@ -62,7 +59,6 @@ fn test_my_filter() {
 | 
				
			|||||||
    assert_eq!(t.render().unwrap(), "faa");
 | 
					    assert_eq!(t.render().unwrap(), "faa");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Template)]
 | 
					#[derive(Template)]
 | 
				
			||||||
#[template(path = "filters_join.html")]
 | 
					#[template(path = "filters_join.html")]
 | 
				
			||||||
struct JoinTemplate<'a> {
 | 
					struct JoinTemplate<'a> {
 | 
				
			||||||
@ -71,7 +67,9 @@ struct JoinTemplate<'a> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[test]
 | 
					#[test]
 | 
				
			||||||
fn test_join() {
 | 
					fn test_join() {
 | 
				
			||||||
    let t = JoinTemplate { s: &["foo", "bar", "bazz"] };
 | 
					    let t = JoinTemplate {
 | 
				
			||||||
 | 
					        s: &["foo", "bar", "bazz"],
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
    assert_eq!(t.render().unwrap(), "foo, bar, bazz");
 | 
					    assert_eq!(t.render().unwrap(), "foo, bar, bazz");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -83,11 +81,12 @@ struct VecJoinTemplate {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[test]
 | 
					#[test]
 | 
				
			||||||
fn test_vec_join() {
 | 
					fn test_vec_join() {
 | 
				
			||||||
    let t = VecJoinTemplate { s: vec!["foo".into(), "bar".into(), "bazz".into()] };
 | 
					    let t = VecJoinTemplate {
 | 
				
			||||||
 | 
					        s: vec!["foo".into(), "bar".into(), "bazz".into()],
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
    assert_eq!(t.render().unwrap(), "foo, bar, bazz");
 | 
					    assert_eq!(t.render().unwrap(), "foo, bar, bazz");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Template)]
 | 
					#[derive(Template)]
 | 
				
			||||||
#[template(path = "json.html")]
 | 
					#[template(path = "json.html")]
 | 
				
			||||||
struct JsonTemplate<'a> {
 | 
					struct JsonTemplate<'a> {
 | 
				
			||||||
@ -98,7 +97,10 @@ struct JsonTemplate<'a> {
 | 
				
			|||||||
#[test]
 | 
					#[test]
 | 
				
			||||||
fn test_json() {
 | 
					fn test_json() {
 | 
				
			||||||
    let val = json!({"arr": [ "one", 2, true, null ]});
 | 
					    let val = json!({"arr": [ "one", 2, true, null ]});
 | 
				
			||||||
    let t = JsonTemplate { foo: "a", bar: &val };
 | 
					    let t = JsonTemplate {
 | 
				
			||||||
 | 
					        foo: "a",
 | 
				
			||||||
 | 
					        bar: &val,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
    // Note: the json filter lacks a way to specify initial indentation
 | 
					    // Note: the json filter lacks a way to specify initial indentation
 | 
				
			||||||
    assert_eq!(
 | 
					    assert_eq!(
 | 
				
			||||||
        t.render().unwrap(),
 | 
					        t.render().unwrap(),
 | 
				
			||||||
@ -116,7 +118,6 @@ fn test_json() {
 | 
				
			|||||||
    );
 | 
					    );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Template)]
 | 
					#[derive(Template)]
 | 
				
			||||||
#[template(source = "{{ x|mytrim|safe }}", ext = "html")]
 | 
					#[template(source = "{{ x|mytrim|safe }}", ext = "html")]
 | 
				
			||||||
struct NestedFilterTemplate {
 | 
					struct NestedFilterTemplate {
 | 
				
			||||||
@ -125,11 +126,12 @@ struct NestedFilterTemplate {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[test]
 | 
					#[test]
 | 
				
			||||||
fn test_nested_filter_ref() {
 | 
					fn test_nested_filter_ref() {
 | 
				
			||||||
    let t = NestedFilterTemplate { x: " floo & bar".to_string() };
 | 
					    let t = NestedFilterTemplate {
 | 
				
			||||||
 | 
					        x: " floo & bar".to_string(),
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
    assert_eq!(t.render().unwrap(), "floo & bar");
 | 
					    assert_eq!(t.render().unwrap(), "floo & bar");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Template)]
 | 
					#[derive(Template)]
 | 
				
			||||||
#[template(source = "{% let p = baz.print(foo.as_ref()) %}{{ p|upper }}", ext = "html")]
 | 
					#[template(source = "{% let p = baz.print(foo.as_ref()) %}{{ p|upper }}", ext = "html")]
 | 
				
			||||||
struct FilterLetFilterTemplate {
 | 
					struct FilterLetFilterTemplate {
 | 
				
			||||||
@ -147,6 +149,9 @@ impl Baz {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[test]
 | 
					#[test]
 | 
				
			||||||
fn test_filter_let_filter() {
 | 
					fn test_filter_let_filter() {
 | 
				
			||||||
    let t = FilterLetFilterTemplate { foo: " bar ".to_owned(), baz: Baz {} };
 | 
					    let t = FilterLetFilterTemplate {
 | 
				
			||||||
 | 
					        foo: " bar ".to_owned(),
 | 
				
			||||||
 | 
					        baz: Baz {},
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
    assert_eq!(t.render().unwrap(), "BAR");
 | 
					    assert_eq!(t.render().unwrap(), "BAR");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -6,7 +6,8 @@ use askama::Template;
 | 
				
			|||||||
#[derive(Template)] // this will generate the code...
 | 
					#[derive(Template)] // this will generate the code...
 | 
				
			||||||
#[template(path = "hello.html")] // using the template in this path, relative
 | 
					#[template(path = "hello.html")] // using the template in this path, relative
 | 
				
			||||||
                                 // to the templates dir in the crate root
 | 
					                                 // to the templates dir in the crate root
 | 
				
			||||||
struct HelloTemplate<'a> { // the name of the struct can be anything
 | 
					struct HelloTemplate<'a> {
 | 
				
			||||||
 | 
					    // the name of the struct can be anything
 | 
				
			||||||
    name: &'a str, // the field name should match the variable name
 | 
					    name: &'a str, // the field name should match the variable name
 | 
				
			||||||
                   // in your template
 | 
					                   // in your template
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -23,14 +23,15 @@ fn test_use_base_directly() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[test]
 | 
					#[test]
 | 
				
			||||||
fn test_simple_extends() {
 | 
					fn test_simple_extends() {
 | 
				
			||||||
    let t = ChildTemplate { _parent: BaseTemplate { title: "Bar" } };
 | 
					    let t = ChildTemplate {
 | 
				
			||||||
 | 
					        _parent: BaseTemplate { title: "Bar" },
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
    assert_eq!(
 | 
					    assert_eq!(
 | 
				
			||||||
        t.render().unwrap(),
 | 
					        t.render().unwrap(),
 | 
				
			||||||
        "Bar\n(Bar) Content goes here\nFoo\nCopyright 2017"
 | 
					        "Bar\n(Bar) Content goes here\nFoo\nCopyright 2017"
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
pub mod parent {
 | 
					pub mod parent {
 | 
				
			||||||
    use askama::Template;
 | 
					    use askama::Template;
 | 
				
			||||||
    #[derive(Template)]
 | 
					    #[derive(Template)]
 | 
				
			||||||
@ -41,8 +42,8 @@ pub mod parent {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub mod child {
 | 
					pub mod child {
 | 
				
			||||||
    use askama::Template;
 | 
					 | 
				
			||||||
    use super::parent::*;
 | 
					    use super::parent::*;
 | 
				
			||||||
 | 
					    use askama::Template;
 | 
				
			||||||
    #[derive(Template)]
 | 
					    #[derive(Template)]
 | 
				
			||||||
    #[template(path = "child.html")]
 | 
					    #[template(path = "child.html")]
 | 
				
			||||||
    pub struct ChildTemplate<'a> {
 | 
					    pub struct ChildTemplate<'a> {
 | 
				
			||||||
@ -52,15 +53,15 @@ pub mod child {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[test]
 | 
					#[test]
 | 
				
			||||||
fn test_different_module() {
 | 
					fn test_different_module() {
 | 
				
			||||||
    let t = child::ChildTemplate { _parent: parent::BaseTemplate { title: "a" } };
 | 
					    let t = child::ChildTemplate {
 | 
				
			||||||
 | 
					        _parent: parent::BaseTemplate { title: "a" },
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
    assert_eq!(
 | 
					    assert_eq!(
 | 
				
			||||||
        t.render().unwrap(),
 | 
					        t.render().unwrap(),
 | 
				
			||||||
        "a\n(a) Content goes here\nFoo\nCopyright 2017"
 | 
					        "a\n(a) Content goes here\nFoo\nCopyright 2017"
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Template)]
 | 
					#[derive(Template)]
 | 
				
			||||||
#[template(path = "nested-base.html")]
 | 
					#[template(path = "nested-base.html")]
 | 
				
			||||||
struct NestedBaseTemplate {}
 | 
					struct NestedBaseTemplate {}
 | 
				
			||||||
@ -73,6 +74,8 @@ struct NestedChildTemplate {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[test]
 | 
					#[test]
 | 
				
			||||||
fn test_nested_blocks() {
 | 
					fn test_nested_blocks() {
 | 
				
			||||||
    let t = NestedChildTemplate { _parent: NestedBaseTemplate {} };
 | 
					    let t = NestedChildTemplate {
 | 
				
			||||||
 | 
					        _parent: NestedBaseTemplate {},
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
    assert_eq!(t.render().unwrap(), "\ndurpy\n");
 | 
					    assert_eq!(t.render().unwrap(), "\ndurpy\n");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -11,11 +11,12 @@ struct ForTemplate<'a> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[test]
 | 
					#[test]
 | 
				
			||||||
fn test_for() {
 | 
					fn test_for() {
 | 
				
			||||||
    let s = ForTemplate { strings: vec!["A", "alfa", "1"] };
 | 
					    let s = ForTemplate {
 | 
				
			||||||
 | 
					        strings: vec!["A", "alfa", "1"],
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
    assert_eq!(s.render().unwrap(), "0. A\n1. alfa\n2. 1\n");
 | 
					    assert_eq!(s.render().unwrap(), "0. A\n1. alfa\n2. 1\n");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Template)]
 | 
					#[derive(Template)]
 | 
				
			||||||
#[template(path = "nested-for.html")]
 | 
					#[template(path = "nested-for.html")]
 | 
				
			||||||
struct NestedForTemplate<'a> {
 | 
					struct NestedForTemplate<'a> {
 | 
				
			||||||
@ -26,6 +27,8 @@ struct NestedForTemplate<'a> {
 | 
				
			|||||||
fn test_nested_for() {
 | 
					fn test_nested_for() {
 | 
				
			||||||
    let alpha = vec!["a", "b", "c"];
 | 
					    let alpha = vec!["a", "b", "c"];
 | 
				
			||||||
    let numbers = vec!["one", "two"];
 | 
					    let numbers = vec!["one", "two"];
 | 
				
			||||||
    let s = NestedForTemplate { seqs: vec![&alpha, &numbers] };
 | 
					    let s = NestedForTemplate {
 | 
				
			||||||
 | 
					        seqs: vec![&alpha, &numbers],
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
    assert_eq!(s.render().unwrap(), "1\n  0a1b2c2\n  0one1two");
 | 
					    assert_eq!(s.render().unwrap(), "1\n  0a1b2c2\n  0one1two");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -15,7 +15,6 @@ struct MatchOptRefTemplate<'a> {
 | 
				
			|||||||
    item: &'a Option<&'a str>,
 | 
					    item: &'a Option<&'a str>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[test]
 | 
					#[test]
 | 
				
			||||||
fn test_match_option() {
 | 
					fn test_match_option() {
 | 
				
			||||||
    let s = MatchOptTemplate { item: Some("foo") };
 | 
					    let s = MatchOptTemplate { item: Some("foo") };
 | 
				
			||||||
@ -79,7 +78,9 @@ struct MatchCustomEnumTemplate {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[test]
 | 
					#[test]
 | 
				
			||||||
fn test_match_custom_enum() {
 | 
					fn test_match_custom_enum() {
 | 
				
			||||||
    let s = MatchCustomEnumTemplate { color: Color::Rgb(160, 0, 255) };
 | 
					    let s = MatchCustomEnumTemplate {
 | 
				
			||||||
 | 
					        color: Color::Rgb(160, 0, 255),
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
    assert_eq!(s.render().unwrap(), "\n\nColorful: #A000FF\n");
 | 
					    assert_eq!(s.render().unwrap(), "\n\nColorful: #A000FF\n");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -21,7 +21,6 @@ fn test_self_method() {
 | 
				
			|||||||
    assert_eq!(t.render().unwrap(), "foo");
 | 
					    assert_eq!(t.render().unwrap(), "foo");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Template)]
 | 
					#[derive(Template)]
 | 
				
			||||||
#[template(source = "{{ self.get_s() }} {{ t.get_s() }}", ext = "txt")]
 | 
					#[template(source = "{{ self.get_s() }} {{ t.get_s() }}", ext = "txt")]
 | 
				
			||||||
struct NestedSelfMethodTemplate<'a> {
 | 
					struct NestedSelfMethodTemplate<'a> {
 | 
				
			||||||
 | 
				
			|||||||
@ -17,7 +17,6 @@ fn test_compare() {
 | 
				
			|||||||
    assert_eq!(t.render().unwrap(), "tf\ntf\ntf\ntf\ntf\ntf");
 | 
					    assert_eq!(t.render().unwrap(), "tf\ntf\ntf\ntf\ntf\ntf");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Template)]
 | 
					#[derive(Template)]
 | 
				
			||||||
#[template(path = "operators.html")]
 | 
					#[template(path = "operators.html")]
 | 
				
			||||||
struct OperatorsTemplate {
 | 
					struct OperatorsTemplate {
 | 
				
			||||||
@ -32,7 +31,6 @@ fn test_operators() {
 | 
				
			|||||||
    assert_eq!(t.render().unwrap(), "muldivmodaddrshlshbandbxorborandor");
 | 
					    assert_eq!(t.render().unwrap(), "muldivmodaddrshlshbandbxorborandor");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Template)]
 | 
					#[derive(Template)]
 | 
				
			||||||
#[template(path = "precedence.html")]
 | 
					#[template(path = "precedence.html")]
 | 
				
			||||||
struct PrecedenceTemplate {}
 | 
					struct PrecedenceTemplate {}
 | 
				
			||||||
 | 
				
			|||||||
@ -8,8 +8,8 @@ extern crate rocket;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use askama::Template;
 | 
					use askama::Template;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use rocket::local::Client;
 | 
					 | 
				
			||||||
use rocket::http::{ContentType, Status};
 | 
					use rocket::http::{ContentType, Status};
 | 
				
			||||||
 | 
					use rocket::local::Client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Template)]
 | 
					#[derive(Template)]
 | 
				
			||||||
#[template(path = "hello.html")]
 | 
					#[template(path = "hello.html")]
 | 
				
			||||||
 | 
				
			|||||||
@ -3,7 +3,6 @@ extern crate askama;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use askama::Template;
 | 
					use askama::Template;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Template)]
 | 
					#[derive(Template)]
 | 
				
			||||||
#[template(path = "simple.html")]
 | 
					#[template(path = "simple.html")]
 | 
				
			||||||
struct VariablesTemplate<'a> {
 | 
					struct VariablesTemplate<'a> {
 | 
				
			||||||
@ -28,7 +27,6 @@ fn test_variables() {
 | 
				
			|||||||
    );
 | 
					    );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Template)]
 | 
					#[derive(Template)]
 | 
				
			||||||
#[template(path = "if.html")]
 | 
					#[template(path = "if.html")]
 | 
				
			||||||
struct IfTemplate {
 | 
					struct IfTemplate {
 | 
				
			||||||
@ -41,7 +39,6 @@ fn test_if() {
 | 
				
			|||||||
    assert_eq!(s.render().unwrap(), "true");
 | 
					    assert_eq!(s.render().unwrap(), "true");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Template)]
 | 
					#[derive(Template)]
 | 
				
			||||||
#[template(path = "else.html")]
 | 
					#[template(path = "else.html")]
 | 
				
			||||||
struct ElseTemplate {
 | 
					struct ElseTemplate {
 | 
				
			||||||
@ -54,7 +51,6 @@ fn test_else() {
 | 
				
			|||||||
    assert_eq!(s.render().unwrap(), "false");
 | 
					    assert_eq!(s.render().unwrap(), "false");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Template)]
 | 
					#[derive(Template)]
 | 
				
			||||||
#[template(path = "else-if.html")]
 | 
					#[template(path = "else-if.html")]
 | 
				
			||||||
struct ElseIfTemplate {
 | 
					struct ElseIfTemplate {
 | 
				
			||||||
@ -64,11 +60,13 @@ struct ElseIfTemplate {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[test]
 | 
					#[test]
 | 
				
			||||||
fn test_else_if() {
 | 
					fn test_else_if() {
 | 
				
			||||||
    let s = ElseIfTemplate { cond: false, check: true };
 | 
					    let s = ElseIfTemplate {
 | 
				
			||||||
 | 
					        cond: false,
 | 
				
			||||||
 | 
					        check: true,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
    assert_eq!(s.render().unwrap(), "checked");
 | 
					    assert_eq!(s.render().unwrap(), "checked");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Template)]
 | 
					#[derive(Template)]
 | 
				
			||||||
#[template(path = "literals.html")]
 | 
					#[template(path = "literals.html")]
 | 
				
			||||||
struct LiteralsTemplate {}
 | 
					struct LiteralsTemplate {}
 | 
				
			||||||
@ -79,7 +77,6 @@ fn test_literals() {
 | 
				
			|||||||
    assert_eq!(s.render().unwrap(), "a");
 | 
					    assert_eq!(s.render().unwrap(), "a");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
struct Holder {
 | 
					struct Holder {
 | 
				
			||||||
    a: usize,
 | 
					    a: usize,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -92,7 +89,9 @@ struct AttrTemplate {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[test]
 | 
					#[test]
 | 
				
			||||||
fn test_attr() {
 | 
					fn test_attr() {
 | 
				
			||||||
    let t = AttrTemplate { inner: Holder { a: 5 } };
 | 
					    let t = AttrTemplate {
 | 
				
			||||||
 | 
					        inner: Holder { a: 5 },
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
    assert_eq!(t.render().unwrap(), "5");
 | 
					    assert_eq!(t.render().unwrap(), "5");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -104,11 +103,12 @@ struct TupleAttrTemplate<'a> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[test]
 | 
					#[test]
 | 
				
			||||||
fn test_tuple_attr() {
 | 
					fn test_tuple_attr() {
 | 
				
			||||||
    let t = TupleAttrTemplate { tuple: ("foo", "bar") };
 | 
					    let t = TupleAttrTemplate {
 | 
				
			||||||
 | 
					        tuple: ("foo", "bar"),
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
    assert_eq!(t.render().unwrap(), "foobar");
 | 
					    assert_eq!(t.render().unwrap(), "foobar");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
struct NestedHolder {
 | 
					struct NestedHolder {
 | 
				
			||||||
    holder: Holder,
 | 
					    holder: Holder,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -121,11 +121,14 @@ struct NestedAttrTemplate {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[test]
 | 
					#[test]
 | 
				
			||||||
fn test_nested_attr() {
 | 
					fn test_nested_attr() {
 | 
				
			||||||
    let t = NestedAttrTemplate { inner: NestedHolder { holder: Holder { a: 5 } } };
 | 
					    let t = NestedAttrTemplate {
 | 
				
			||||||
 | 
					        inner: NestedHolder {
 | 
				
			||||||
 | 
					            holder: Holder { a: 5 },
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
    assert_eq!(t.render().unwrap(), "5");
 | 
					    assert_eq!(t.render().unwrap(), "5");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Template)]
 | 
					#[derive(Template)]
 | 
				
			||||||
#[template(path = "option.html")]
 | 
					#[template(path = "option.html")]
 | 
				
			||||||
struct OptionTemplate<'a> {
 | 
					struct OptionTemplate<'a> {
 | 
				
			||||||
@ -140,11 +143,12 @@ fn test_option() {
 | 
				
			|||||||
    assert_eq!(none.render().unwrap(), "none");
 | 
					    assert_eq!(none.render().unwrap(), "none");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Template)]
 | 
					#[derive(Template)]
 | 
				
			||||||
#[template(path = "generics.html")]
 | 
					#[template(path = "generics.html")]
 | 
				
			||||||
struct GenericsTemplate<T: std::fmt::Display, U = u8>
 | 
					struct GenericsTemplate<T: std::fmt::Display, U = u8>
 | 
				
			||||||
    where U: std::fmt::Display {
 | 
					where
 | 
				
			||||||
 | 
					    U: std::fmt::Display,
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    t: T,
 | 
					    t: T,
 | 
				
			||||||
    u: U,
 | 
					    u: U,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -155,7 +159,6 @@ fn test_generics() {
 | 
				
			|||||||
    assert_eq!(t.render().unwrap(), "a42");
 | 
					    assert_eq!(t.render().unwrap(), "a42");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Template)]
 | 
					#[derive(Template)]
 | 
				
			||||||
#[template(path = "composition.html")]
 | 
					#[template(path = "composition.html")]
 | 
				
			||||||
struct CompositionTemplate {
 | 
					struct CompositionTemplate {
 | 
				
			||||||
@ -164,11 +167,12 @@ struct CompositionTemplate {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[test]
 | 
					#[test]
 | 
				
			||||||
fn test_composition() {
 | 
					fn test_composition() {
 | 
				
			||||||
    let t = CompositionTemplate { foo: IfTemplate { cond: true } };
 | 
					    let t = CompositionTemplate {
 | 
				
			||||||
 | 
					        foo: IfTemplate { cond: true },
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
    assert_eq!(t.render().unwrap(), "composed: true");
 | 
					    assert_eq!(t.render().unwrap(), "composed: true");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(PartialEq, Eq)]
 | 
					#[derive(PartialEq, Eq)]
 | 
				
			||||||
enum Alphabet {
 | 
					enum Alphabet {
 | 
				
			||||||
    Alpha,
 | 
					    Alpha,
 | 
				
			||||||
@ -186,7 +190,6 @@ fn test_path_compare() {
 | 
				
			|||||||
    assert_eq!(t.render().unwrap(), "true");
 | 
					    assert_eq!(t.render().unwrap(), "true");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Template)]
 | 
					#[derive(Template)]
 | 
				
			||||||
#[template(source = "{% for i in [\"a\", \"\"] %}{{ i }}{% endfor %}", ext = "txt")]
 | 
					#[template(source = "{% for i in [\"a\", \"\"] %}{{ i }}{% endfor %}", ext = "txt")]
 | 
				
			||||||
struct ArrayTemplate {}
 | 
					struct ArrayTemplate {}
 | 
				
			||||||
@ -197,7 +200,6 @@ fn test_slice_literal() {
 | 
				
			|||||||
    assert_eq!(t.render().unwrap(), "a");
 | 
					    assert_eq!(t.render().unwrap(), "a");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Template)]
 | 
					#[derive(Template)]
 | 
				
			||||||
#[template(source = "  {# foo -#} ", ext = "txt")]
 | 
					#[template(source = "  {# foo -#} ", ext = "txt")]
 | 
				
			||||||
struct CommentTemplate {}
 | 
					struct CommentTemplate {}
 | 
				
			||||||
@ -208,7 +210,6 @@ fn test_comment() {
 | 
				
			|||||||
    assert_eq!(t.render().unwrap(), "  ");
 | 
					    assert_eq!(t.render().unwrap(), "  ");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Template)]
 | 
					#[derive(Template)]
 | 
				
			||||||
#[template(source = "{% if !foo %}Hello{% endif %}", ext = "txt")]
 | 
					#[template(source = "{% if !foo %}Hello{% endif %}", ext = "txt")]
 | 
				
			||||||
struct NegationTemplate {
 | 
					struct NegationTemplate {
 | 
				
			||||||
@ -221,7 +222,6 @@ fn test_negation() {
 | 
				
			|||||||
    assert_eq!(t.render().unwrap(), "Hello");
 | 
					    assert_eq!(t.render().unwrap(), "Hello");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Template)]
 | 
					#[derive(Template)]
 | 
				
			||||||
#[template(source = "{% if foo > -2 %}Hello{% endif %}", ext = "txt")]
 | 
					#[template(source = "{% if foo > -2 %}Hello{% endif %}", ext = "txt")]
 | 
				
			||||||
struct MinusTemplate {
 | 
					struct MinusTemplate {
 | 
				
			||||||
 | 
				
			|||||||
@ -15,7 +15,6 @@ fn test_let() {
 | 
				
			|||||||
    assert_eq!(t.render().unwrap(), "foo");
 | 
					    assert_eq!(t.render().unwrap(), "foo");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Template)]
 | 
					#[derive(Template)]
 | 
				
			||||||
#[template(path = "let-decl.html")]
 | 
					#[template(path = "let-decl.html")]
 | 
				
			||||||
struct LetDeclTemplate<'a> {
 | 
					struct LetDeclTemplate<'a> {
 | 
				
			||||||
@ -25,6 +24,9 @@ struct LetDeclTemplate<'a> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[test]
 | 
					#[test]
 | 
				
			||||||
fn test_let_decl() {
 | 
					fn test_let_decl() {
 | 
				
			||||||
    let t = LetDeclTemplate { cond: false, s: "bar" };
 | 
					    let t = LetDeclTemplate {
 | 
				
			||||||
 | 
					        cond: false,
 | 
				
			||||||
 | 
					        s: "bar",
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
    assert_eq!(t.render().unwrap(), "bar");
 | 
					    assert_eq!(t.render().unwrap(), "bar");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user