From eb4ceae2a31674293e2846d58fa705a4cd8db0b9 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 26 Jul 2024 22:05:19 +0200 Subject: [PATCH 1/2] Store bool for BoolLit instead of str --- rinja_derive/src/generator.rs | 8 ++++++-- rinja_parser/src/expr.rs | 6 +++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/rinja_derive/src/generator.rs b/rinja_derive/src/generator.rs index 74e0fb37..fd37d37f 100644 --- a/rinja_derive/src/generator.rs +++ b/rinja_derive/src/generator.rs @@ -1888,8 +1888,12 @@ impl<'a> Generator<'a> { DisplayWrap::Wrapped } - fn visit_bool_lit(&mut self, buf: &mut Buffer, s: &str) -> DisplayWrap { - buf.write(s); + fn visit_bool_lit(&mut self, buf: &mut Buffer, s: bool) -> DisplayWrap { + if s { + buf.write("true"); + } else { + buf.write("false"); + } DisplayWrap::Unwrapped } diff --git a/rinja_parser/src/expr.rs b/rinja_parser/src/expr.rs index a527b756..5e87e19a 100644 --- a/rinja_parser/src/expr.rs +++ b/rinja_parser/src/expr.rs @@ -35,7 +35,7 @@ macro_rules! expr_prec_layer { #[derive(Clone, Debug, PartialEq)] pub enum Expr<'a> { - BoolLit(&'a str), + BoolLit(bool), NumLit(&'a str), StrLit(&'a str), CharLit(&'a str), @@ -334,8 +334,8 @@ impl<'a> Expr<'a> { let start = i; map(path_or_identifier, |v| match v { PathOrIdentifier::Path(v) => Self::Path(v), - PathOrIdentifier::Identifier(v @ "true") => Self::BoolLit(v), - PathOrIdentifier::Identifier(v @ "false") => Self::BoolLit(v), + PathOrIdentifier::Identifier("true") => Self::BoolLit(true), + PathOrIdentifier::Identifier("false") => Self::BoolLit(false), PathOrIdentifier::Identifier(v) => Self::Var(v), })(i) .map(|(i, expr)| (i, WithSpan::new(expr, start))) From 96be934fe46f08995e0309ac0662e561274783fc Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 26 Jul 2024 22:16:34 +0200 Subject: [PATCH 2/2] Add handling of boolean literals to condition evaluation --- rinja_derive/src/generator.rs | 5 +- rinja_derive/src/tests.rs | 92 +++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 2 deletions(-) diff --git a/rinja_derive/src/generator.rs b/rinja_derive/src/generator.rs index fd37d37f..fa0ef79a 100644 --- a/rinja_derive/src/generator.rs +++ b/rinja_derive/src/generator.rs @@ -372,8 +372,7 @@ impl<'a> Generator<'a> { only_contains_is_defined: &mut bool, ) -> EvaluatedResult { match **expr { - Expr::BoolLit(_) - | Expr::NumLit(_) + Expr::NumLit(_) | Expr::StrLit(_) | Expr::CharLit(_) | Expr::Var(_) @@ -392,6 +391,8 @@ impl<'a> Generator<'a> { *only_contains_is_defined = false; EvaluatedResult::Unknown } + Expr::BoolLit(true) => EvaluatedResult::AlwaysTrue, + Expr::BoolLit(false) => EvaluatedResult::AlwaysFalse, Expr::Unary("!", ref inner) => { match self.evaluate_condition(inner, only_contains_is_defined) { EvaluatedResult::AlwaysTrue => EvaluatedResult::AlwaysFalse, diff --git a/rinja_derive/src/tests.rs b/rinja_derive/src/tests.rs index 68f95699..e03de670 100644 --- a/rinja_derive/src/tests.rs +++ b/rinja_derive/src/tests.rs @@ -334,3 +334,95 @@ writer.write_str("12")?; 3, ); } + +#[test] +fn check_bool_conditions() { + // Checks that it removes conditions if we know at compile-time that they always return false. + // + // We're forced to add `bla` otherwise `compare` assert fails in weird ways... + compare( + "{% if false %}{{query}}{% endif %}bla", + r#"writer.write_str("bla")?;"#, + &[], + 3, + ); + compare( + "{% if false && false %}{{query}}{% endif %}bla", + r#"writer.write_str("bla")?;"#, + &[], + 3, + ); + compare( + "{% if false && true %}{{query}}{% endif %}bla", + r#"writer.write_str("bla")?;"#, + &[], + 3, + ); + compare( + "{% if true && false %}{{query}}{% endif %}bla", + r#"writer.write_str("bla")?;"#, + &[], + 3, + ); + compare( + "{% if false || true %}bli{% endif %}bla", + r#"writer.write_str("blibla")?;"#, + &[], + 6, + ); + compare( + "{% if true || false %}bli{% endif %}bla", + r#"writer.write_str("blibla")?;"#, + &[], + 6, + ); + + compare( + "{% if true || x == 12 %}{{x}}{% endif %}", + r#"if *(&(true || self.x == 12) as &bool) { + match ( + &((&&::rinja::filters::AutoEscaper::new(&(self.x), ::rinja::filters::Text)).rinja_auto_escape()?), + ) { + (expr0,) => { + (&&::rinja::filters::Writable(expr0)).rinja_write(writer)?; + } + } +} +"#, + &[("x", "u32")], + 3, + ); + compare( + "{% if false || x == 12 %}{{x}}{% endif %}", + r#"if *(&(false || self.x == 12) as &bool) { + match ( + &((&&::rinja::filters::AutoEscaper::new( + &(self.x), + ::rinja::filters::Text, + )) + .rinja_auto_escape()?), + ) { + (expr0,) => { + (&&::rinja::filters::Writable(expr0)).rinja_write(writer)?; + } + } +} +"#, + &[("x", "u32")], + 3, + ); + + // Some funny cases. + compare( + "{% if !(false) %}bla{% endif %}", + r#"writer.write_str("bla")?;"#, + &[], + 3, + ); + compare( + "{% if !(true) %}{{query}}{% endif %}bla", + r#"writer.write_str("bla")?;"#, + &[], + 3, + ); +}