diff options
Diffstat (limited to 'askama_derive/src/config.rs')
-rw-r--r-- | askama_derive/src/config.rs | 110 |
1 files changed, 94 insertions, 16 deletions
diff --git a/askama_derive/src/config.rs b/askama_derive/src/config.rs index cf22a72..f01bd65 100644 --- a/askama_derive/src/config.rs +++ b/askama_derive/src/config.rs @@ -168,24 +168,34 @@ impl<'a> TryFrom<RawSyntax<'a>> for Syntax<'a> { comment_end: raw.comment_end.unwrap_or(default.comment_end), }; - if syntax.block_start.len() != 2 - || syntax.block_end.len() != 2 - || syntax.expr_start.len() != 2 - || syntax.expr_end.len() != 2 - || syntax.comment_start.len() != 2 - || syntax.comment_end.len() != 2 - { - return Err("length of delimiters must be two".into()); + for s in [ + syntax.block_start, + syntax.block_end, + syntax.expr_start, + syntax.expr_end, + syntax.comment_start, + syntax.comment_end, + ] { + if s.len() < 2 { + return Err( + format!("delimiters must be at least two characters long: {s:?}").into(), + ); + } else if s.chars().any(|c| c.is_whitespace()) { + return Err(format!("delimiters may not contain white spaces: {s:?}").into()); + } } - let bs = syntax.block_start.as_bytes()[0]; - let be = syntax.block_start.as_bytes()[1]; - let cs = syntax.comment_start.as_bytes()[0]; - let ce = syntax.comment_start.as_bytes()[1]; - let es = syntax.expr_start.as_bytes()[0]; - let ee = syntax.expr_start.as_bytes()[1]; - if !((bs == cs && bs == es) || (be == ce && be == ee)) { - return Err(format!("bad delimiters block_start: {}, comment_start: {}, expr_start: {}, needs one of the two characters in common", syntax.block_start, syntax.comment_start, syntax.expr_start).into()); + for (s1, s2) in [ + (syntax.block_start, syntax.expr_start), + (syntax.block_start, syntax.comment_start), + (syntax.expr_start, syntax.comment_start), + ] { + if s1.starts_with(s2) || s2.starts_with(s1) { + return Err(format!( + "a delimiter may not be the prefix of another delimiter: {s1:?} vs {s2:?}", + ) + .into()); + } } Ok(syntax) @@ -452,6 +462,74 @@ mod tests { assert_eq!(bar.comment_end, default_syntax.comment_end); } + #[cfg(feature = "config")] + #[test] + fn longer_delimiters() { + let raw_config = r#" + [[syntax]] + name = "emoji" + block_start = "👉🙂👉" + block_end = "👈🙃👈" + expr_start = "🤜🤜" + expr_end = "🤛🤛" + comment_start = "👎_(ツ)_👎" + comment_end = "👍:D👍" + + [general] + default_syntax = "emoji" + "#; + + let config = Config::new(raw_config, None).unwrap(); + assert_eq!(config.default_syntax, "emoji"); + + let foo = config.syntaxes.get("emoji").unwrap(); + assert_eq!(foo.block_start, "👉🙂👉"); + assert_eq!(foo.block_end, "👈🙃👈"); + assert_eq!(foo.expr_start, "🤜🤜"); + assert_eq!(foo.expr_end, "🤛🤛"); + assert_eq!(foo.comment_start, "👎_(ツ)_👎"); + assert_eq!(foo.comment_end, "👍:D👍"); + } + + #[cfg(feature = "config")] + #[test] + fn illegal_delimiters() { + let raw_config = r#" + [[syntax]] + name = "too_short" + block_start = "<" + "#; + let config = Config::new(raw_config, None); + assert_eq!( + config.unwrap_err().msg, + r#"delimiters must be at least two characters long: "<""#, + ); + + let raw_config = r#" + [[syntax]] + name = "contains_ws" + block_start = " {{ " + "#; + let config = Config::new(raw_config, None); + assert_eq!( + config.unwrap_err().msg, + r#"delimiters may not contain white spaces: " {{ ""#, + ); + + let raw_config = r#" + [[syntax]] + name = "is_prefix" + block_start = "{{" + expr_start = "{{$" + comment_start = "{{#" + "#; + let config = Config::new(raw_config, None); + assert_eq!( + config.unwrap_err().msg, + r#"a delimiter may not be the prefix of another delimiter: "{{" vs "{{$""#, + ); + } + #[cfg(feature = "toml")] #[should_panic] #[test] |