diff options
author | René Kijewski <rene.kijewski@fu-berlin.de> | 2023-01-24 09:21:52 +0100 |
---|---|---|
committer | Dirkjan Ochtman <dirkjan@ochtman.nl> | 2023-01-30 10:10:49 +0100 |
commit | 58e02a4fb6f6d58ff68d18f24abcfc8cab53f7be (patch) | |
tree | 2436bc202212b34ec25f7cd143c2f2285966ae50 /askama_derive | |
parent | 3003d86264680433e789d2726d0d12d2c6267c40 (diff) | |
download | askama-58e02a4fb6f6d58ff68d18f24abcfc8cab53f7be.tar.gz askama-58e02a4fb6f6d58ff68d18f24abcfc8cab53f7be.tar.bz2 askama-58e02a4fb6f6d58ff68d18f24abcfc8cab53f7be.zip |
derive: Make Config `'static`
The configuration is made `'static`, because `toml` and `toml_edit` both
needs to implement serde's `DeserializeOwned` by now. We allocate the
strings once per template, so it is very unlikely that this change will
have any measurable impact, neither in compile time nor RAM usage.
Diffstat (limited to '')
-rw-r--r-- | askama_derive/src/config.rs | 95 | ||||
-rw-r--r-- | askama_derive/src/heritage.rs | 2 | ||||
-rw-r--r-- | askama_derive/src/input.rs | 8 | ||||
-rw-r--r-- | askama_derive/src/parser.rs | 33 |
4 files changed, 67 insertions, 71 deletions
diff --git a/askama_derive/src/config.rs b/askama_derive/src/config.rs index 8c49217..4dcf1ea 100644 --- a/askama_derive/src/config.rs +++ b/askama_derive/src/config.rs @@ -1,4 +1,5 @@ use std::collections::{BTreeMap, HashSet}; +use std::convert::TryFrom; use std::path::{Path, PathBuf}; use std::{env, fs}; @@ -8,16 +9,16 @@ use serde::Deserialize; use crate::CompileError; #[derive(Debug)] -pub(crate) struct Config<'a> { +pub(crate) struct Config { pub(crate) dirs: Vec<PathBuf>, - pub(crate) syntaxes: BTreeMap<String, Syntax<'a>>, - pub(crate) default_syntax: &'a str, + pub(crate) syntaxes: BTreeMap<String, Syntax>, + pub(crate) default_syntax: String, pub(crate) escapers: Vec<(HashSet<String>, String)>, pub(crate) whitespace: WhitespaceHandling, } -impl Config<'_> { - pub(crate) fn new(s: &str) -> std::result::Result<Config<'_>, CompileError> { +impl Config { + pub(crate) fn new(s: &str) -> std::result::Result<Config, CompileError> { let root = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); let default_dirs = vec![root.join("templates")]; @@ -39,19 +40,19 @@ impl Config<'_> { dirs.map_or(default_dirs, |v| { v.into_iter().map(|dir| root.join(dir)).collect() }), - default_syntax.unwrap_or(DEFAULT_SYNTAX_NAME), + default_syntax.unwrap_or_else(|| DEFAULT_SYNTAX_NAME.to_owned()), whitespace, ), None => ( default_dirs, - DEFAULT_SYNTAX_NAME, + DEFAULT_SYNTAX_NAME.to_owned(), WhitespaceHandling::default(), ), }; if let Some(raw_syntaxes) = raw.syntax { for raw_s in raw_syntaxes { - let name = raw_s.name; + let name = raw_s.name.clone(); if syntaxes .insert(name.to_string(), Syntax::try_from(raw_s)?) @@ -62,7 +63,7 @@ impl Config<'_> { } } - if !syntaxes.contains_key(default_syntax) { + if !syntaxes.contains_key(&default_syntax) { return Err(format!("default syntax \"{default_syntax}\" not found").into()); } @@ -120,32 +121,32 @@ impl Config<'_> { } #[derive(Debug)] -pub(crate) struct Syntax<'a> { - pub(crate) block_start: &'a str, - pub(crate) block_end: &'a str, - pub(crate) expr_start: &'a str, - pub(crate) expr_end: &'a str, - pub(crate) comment_start: &'a str, - pub(crate) comment_end: &'a str, +pub(crate) struct Syntax { + pub(crate) block_start: String, + pub(crate) block_end: String, + pub(crate) expr_start: String, + pub(crate) expr_end: String, + pub(crate) comment_start: String, + pub(crate) comment_end: String, } -impl Default for Syntax<'_> { +impl Default for Syntax { fn default() -> Self { Self { - block_start: "{%", - block_end: "%}", - expr_start: "{{", - expr_end: "}}", - comment_start: "{#", - comment_end: "#}", + block_start: "{%".to_owned(), + block_end: "%}".to_owned(), + expr_start: "{{".to_owned(), + expr_end: "}}".to_owned(), + comment_start: "{#".to_owned(), + comment_end: "#}".to_owned(), } } } -impl<'a> TryFrom<RawSyntax<'a>> for Syntax<'a> { +impl TryFrom<RawSyntax> for Syntax { type Error = CompileError; - fn try_from(raw: RawSyntax<'a>) -> std::result::Result<Self, Self::Error> { + fn try_from(raw: RawSyntax) -> std::result::Result<Self, Self::Error> { let default = Self::default(); let syntax = Self { block_start: raw.block_start.unwrap_or(default.block_start), @@ -182,21 +183,20 @@ impl<'a> TryFrom<RawSyntax<'a>> for Syntax<'a> { #[cfg_attr(feature = "serde", derive(Deserialize))] #[derive(Default)] -struct RawConfig<'d> { - #[cfg_attr(feature = "serde", serde(borrow))] - general: Option<General<'d>>, - syntax: Option<Vec<RawSyntax<'d>>>, - escaper: Option<Vec<RawEscaper<'d>>>, +struct RawConfig { + general: Option<General>, + syntax: Option<Vec<RawSyntax>>, + escaper: Option<Vec<RawEscaper>>, } -impl RawConfig<'_> { +impl RawConfig { #[cfg(feature = "config")] - fn from_toml_str(s: &str) -> std::result::Result<RawConfig<'_>, CompileError> { + fn from_toml_str(s: &str) -> std::result::Result<RawConfig, CompileError> { toml::from_str(s).map_err(|e| format!("invalid TOML in {CONFIG_FILE_NAME}: {e}").into()) } #[cfg(not(feature = "config"))] - fn from_toml_str(_: &str) -> std::result::Result<RawConfig<'_>, CompileError> { + fn from_toml_str(_: &str) -> std::result::Result<RawConfig, CompileError> { Err("TOML support not available".into()) } } @@ -222,29 +222,28 @@ impl Default for WhitespaceHandling { } #[cfg_attr(feature = "serde", derive(Deserialize))] -struct General<'a> { - #[cfg_attr(feature = "serde", serde(borrow))] - dirs: Option<Vec<&'a str>>, - default_syntax: Option<&'a str>, +struct General { + dirs: Option<Vec<String>>, + default_syntax: Option<String>, #[cfg_attr(feature = "serde", serde(default))] whitespace: WhitespaceHandling, } #[cfg_attr(feature = "serde", derive(Deserialize))] -struct RawSyntax<'a> { - name: &'a str, - block_start: Option<&'a str>, - block_end: Option<&'a str>, - expr_start: Option<&'a str>, - expr_end: Option<&'a str>, - comment_start: Option<&'a str>, - comment_end: Option<&'a str>, +struct RawSyntax { + name: String, + block_start: Option<String>, + block_end: Option<String>, + expr_start: Option<String>, + expr_end: Option<String>, + comment_start: Option<String>, + comment_end: Option<String>, } #[cfg_attr(feature = "serde", derive(Deserialize))] -struct RawEscaper<'a> { - path: &'a str, - extensions: Vec<&'a str>, +struct RawEscaper { + path: String, + extensions: Vec<String>, } pub(crate) fn read_config_file( diff --git a/askama_derive/src/heritage.rs b/askama_derive/src/heritage.rs index 9556145..010f723 100644 --- a/askama_derive/src/heritage.rs +++ b/askama_derive/src/heritage.rs @@ -44,7 +44,7 @@ pub(crate) struct Context<'a> { impl Context<'_> { pub(crate) fn new<'n>( - config: &Config<'_>, + config: &Config, path: &Path, nodes: &'n [Node<'n>], ) -> Result<Context<'n>, CompileError> { diff --git a/askama_derive/src/input.rs b/askama_derive/src/input.rs index 47d51bd..b8a0da4 100644 --- a/askama_derive/src/input.rs +++ b/askama_derive/src/input.rs @@ -9,8 +9,8 @@ use mime::Mime; pub(crate) struct TemplateInput<'a> { pub(crate) ast: &'a syn::DeriveInput, - pub(crate) config: &'a Config<'a>, - pub(crate) syntax: &'a Syntax<'a>, + pub(crate) config: &'a Config, + pub(crate) syntax: &'a Syntax, pub(crate) source: Source, pub(crate) print: Print, pub(crate) escaper: &'a str, @@ -25,7 +25,7 @@ impl TemplateInput<'_> { /// `template()` attribute list fields. pub(crate) fn new<'n>( ast: &'n syn::DeriveInput, - config: &'n Config<'_>, + config: &'n Config, args: TemplateArgs, ) -> Result<TemplateInput<'n>, CompileError> { let TemplateArgs { @@ -51,7 +51,7 @@ impl TemplateInput<'_> { // Validate syntax let syntax = syntax.map_or_else( - || Ok(config.syntaxes.get(config.default_syntax).unwrap()), + || Ok(config.syntaxes.get(&config.default_syntax).unwrap()), |s| { config .syntaxes diff --git a/askama_derive/src/parser.rs b/askama_derive/src/parser.rs index c59177a..bcf9c58 100644 --- a/askama_derive/src/parser.rs +++ b/askama_derive/src/parser.rs @@ -250,15 +250,15 @@ fn keyword<'a>(k: &'a str) -> impl FnMut(&'a str) -> IResult<&'a str, &'a str> { } struct State<'a> { - syntax: &'a Syntax<'a>, + syntax: &'a Syntax, loop_depth: Cell<usize>, } fn take_content<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, Node<'a>> { let p_start = alt(( - tag(s.syntax.block_start), - tag(s.syntax.comment_start), - tag(s.syntax.expr_start), + tag(s.syntax.block_start.as_str()), + tag(s.syntax.comment_start.as_str()), + tag(s.syntax.expr_start.as_str()), )); let (i, _) = not(eof)(i)?; @@ -1162,8 +1162,8 @@ fn block_node<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, Node<'a>> { fn block_comment_body<'a>(mut i: &'a str, s: &State<'_>) -> IResult<&'a str, &'a str> { let mut level = 0; loop { - let (end, tail) = take_until(s.syntax.comment_end)(i)?; - match take_until::<_, _, Error<_>>(s.syntax.comment_start)(i) { + let (end, tail) = take_until(s.syntax.comment_end.as_str())(i)?; + match take_until::<_, _, Error<_>>(s.syntax.comment_start.as_str())(i) { Ok((start, _)) if start.as_ptr() < end.as_ptr() => { level += 1; i = &start[2..]; @@ -1209,28 +1209,25 @@ fn parse_template<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, Vec<Node<'a } fn tag_block_start<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, &'a str> { - tag(s.syntax.block_start)(i) + tag(s.syntax.block_start.as_str())(i) } fn tag_block_end<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, &'a str> { - tag(s.syntax.block_end)(i) + tag(s.syntax.block_end.as_str())(i) } fn tag_comment_start<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, &'a str> { - tag(s.syntax.comment_start)(i) + tag(s.syntax.comment_start.as_str())(i) } fn tag_comment_end<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, &'a str> { - tag(s.syntax.comment_end)(i) + tag(s.syntax.comment_end.as_str())(i) } fn tag_expr_start<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, &'a str> { - tag(s.syntax.expr_start)(i) + tag(s.syntax.expr_start.as_str())(i) } fn tag_expr_end<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, &'a str> { - tag(s.syntax.expr_end)(i) + tag(s.syntax.expr_end.as_str())(i) } -pub(crate) fn parse<'a>( - src: &'a str, - syntax: &'a Syntax<'a>, -) -> Result<Vec<Node<'a>>, CompileError> { +pub(crate) fn parse<'a>(src: &'a str, syntax: &'a Syntax) -> Result<Vec<Node<'a>>, CompileError> { let state = State { syntax, loop_depth: Cell::new(0), @@ -1498,8 +1495,8 @@ mod tests { #[test] fn change_delimiters_parse_filter() { let syntax = Syntax { - expr_start: "{=", - expr_end: "=}", + expr_start: "{=".to_owned(), + expr_end: "=}".to_owned(), ..Syntax::default() }; |