case on type-name (match-like) (variant of enum)
What if we have an enum and we would like to display different things based on the variant of the enum? We can use the case and when keywords. They are not as powerful as the match operator in Rust,
but they are useful in this situation.
Cargo.toml
We need both liquid and serde with the derive feature as dependencies:
[package]
name = "liquid-hello-world"
version = "0.1.0"
edition = "2024"
[dependencies]
liquid = "0.26"
serde = { version = "1.0.226", features = ["derive"] }
Code
In this example too I used a template embedded in the Rust code. In a real application I'd put the templates in separate files, but in such an example it is easier to have just one file.
As you can see the Color enum has 3 variants (Red, Green, Blue), but the template only handle 2 (Blue and Green). We do handle "all other cases" with the else keyword, but that's actually not required.
This example would work perfectly fine if we left out the else part. (Obviously the 3rd example would not print the text and the assert would fail.)
#[derive(serde::Serialize)] enum Color { Blue, Green, Red, } fn main() { let template = r#" {% case color %} {% when "Blue" %} blue {% when "Green" %} green {% else %} Unrecognized color {% endcase %} "#; let template = liquid::ParserBuilder::with_stdlib() .build() .unwrap() .parse(template) .unwrap(); // 1st let globals = liquid::object!({ "color": Color::Blue, }); let output = template.render(&globals).unwrap(); println!("{output}"); assert_eq!(output.trim(), "blue"); // 2nd let globals = liquid::object!({ "color": Color::Green, }); let output = template.render(&globals).unwrap(); println!("{}", output); assert_eq!(output.trim(), "green"); // 3rd let globals = liquid::object!({ "color": Color::Red, }); let output = template.render(&globals).unwrap(); println!("{}", output); assert_eq!(output.trim(), "Unrecognized color"); }
Output
blue
green
Unrecognized color
- enum
- case
- when
- else