diff options
author | vallentin <mail@vallentin.dev> | 2020-12-23 15:04:54 +0100 |
---|---|---|
committer | Dirkjan Ochtman <dirkjan@ochtman.nl> | 2020-12-25 22:42:44 +0100 |
commit | fd4ece308e851afe0653ab2b2ad2060914de7486 (patch) | |
tree | 6891dda6bf8439c679e2433a7c7d60f70ed01f2b /askama_shared | |
parent | c7697cbd406dce0962618e99a6b78116b14fdb1c (diff) | |
download | askama-fd4ece308e851afe0653ab2b2ad2060914de7486.tar.gz askama-fd4ece308e851afe0653ab2b2ad2060914de7486.tar.bz2 askama-fd4ece308e851afe0653ab2b2ad2060914de7486.zip |
Added support for redefining variables (fixes #329)
Diffstat (limited to 'askama_shared')
-rw-r--r-- | askama_shared/src/generator.rs | 39 |
1 files changed, 34 insertions, 5 deletions
diff --git a/askama_shared/src/generator.rs b/askama_shared/src/generator.rs index ab964e9..b5f98ec 100644 --- a/askama_shared/src/generator.rs +++ b/askama_shared/src/generator.rs @@ -876,16 +876,34 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> { match *var { Target::Name(name) => { - if !self.locals.contains(&name) { + let meta = self.locals.get(&name).cloned(); + + let shadowed = matches!(&meta, Some(meta) if meta.initialized); + if shadowed { + // Need to flush the buffer if the variable is being shadowed, + // to ensure the old variable is used. + self.write_buf_writable(buf)?; + } + if shadowed || meta.is_none() { buf.write("let "); - self.locals.insert_with_default(name); } buf.write(name); + + self.locals.insert(name, LocalMeta::initialized()); } Target::Tuple(ref targets) => { + let shadowed = targets + .iter() + .any(|name| matches!(self.locals.get(&name), Some(meta) if meta.initialized)); + if shadowed { + // Need to flush the buffer if the variable is being shadowed, + // to ensure the old variable is used. + self.write_buf_writable(buf)?; + } + buf.write("let ("); for name in targets { - self.locals.insert_with_default(name); + self.locals.insert(name, LocalMeta::initialized()); buf.write(name); buf.write(","); } @@ -1576,14 +1594,25 @@ impl Buffer { } } -#[derive(Default)] +#[derive(Clone, Default)] struct LocalMeta { refs: Option<String>, + initialized: bool, } impl LocalMeta { + fn initialized() -> Self { + Self { + refs: None, + initialized: true, + } + } + fn with_ref(refs: String) -> Self { - Self { refs: Some(refs) } + Self { + refs: Some(refs), + initialized: true, + } } } |