aboutsummaryrefslogtreecommitdiffstats
path: root/askama_derive
diff options
context:
space:
mode:
authorLibravatar RenΓ© Kijewski <kijewski@library.vetmed.fu-berlin.de>2023-04-03 18:34:33 +0200
committerLibravatar Dirkjan Ochtman <dirkjan@ochtman.nl>2023-05-31 17:29:22 +0200
commitfe5d350f50ebc73300456c618dd265cc43a8f05a (patch)
tree62248a4f9a1137a1bbae114172f3eebfb0fa5032 /askama_derive
parenta3ff30a5eaca6ffcf82dd152affef4725acf0aa8 (diff)
downloadaskama-fe5d350f50ebc73300456c618dd265cc43a8f05a.tar.gz
askama-fe5d350f50ebc73300456c618dd265cc43a8f05a.tar.bz2
askama-fe5d350f50ebc73300456c618dd265cc43a8f05a.zip
Allow delimiters with arbitrary length
Diffstat (limited to 'askama_derive')
-rw-r--r--askama_derive/src/config.rs110
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]