From 5d014484a4a34146bc13a578e81ed0a0080d4697 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Tue, 9 Jun 2026 14:28:36 -0700 Subject: Loops seem to work!? --- src/lib.rs | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) (limited to 'src/lib.rs') diff --git a/src/lib.rs b/src/lib.rs index a2bfc37..c900e39 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -59,13 +59,14 @@ type Properties = HashMap; #[derive(Debug)] enum Token { + Loop(Identifier, Vec), Show(Identifier,Properties), Text(String), } #[derive(Debug,Clone)] pub enum Value { - Dictionary(HashMap), + Dictionary(Context), List(Vec), String(String), Int(i64), @@ -232,6 +233,16 @@ impl Crimtag { fn exec(input: &impl MappedStructure, tokens: &Vec, buf: &mut String) -> Result<(),ParseError> { for token in tokens { match token { + Token::Loop(ident,code) => { + if let Some(value) = input.get_value( &ident ) && + let Value::List(list) = value { + for rec in &list { + if let Value::Dictionary(d) = rec { + exec( d, code, buf )? + } + } + } + } Token::Show(ident,p) => { let format = if let Some(s) = p.get("format") { s @@ -333,4 +344,46 @@ Now with explicit outputs: } } } + + #[test] + fn loops() { + let mut ct = Crimtag::new(); + if let Err(e) = ct.load_static(r#"Looping code: +[|view "index"|>We will enumerate people here:[|loop people|> + - [|show last_name|], [|show first_name|]: [|show title|]<|loop|] +<|view|] +"#) { + println!("Error: {:?}", e ); + return; + } + + let ctx = Context::from([ + ("people".to_string(), crate::Value::List(vec![ + crate::Value::Dictionary(Context::from([ + ("first_name".to_string(), Value::String("Joe".to_string())), + ("last_name".to_string(), Value::String("Smith".to_string())), + ("title".to_string(), Value::String("CEO".to_string())), + ])), + crate::Value::Dictionary(Context::from([ + ("first_name".to_string(), Value::String("Chris".to_string())), + ("last_name".to_string(), Value::String("Perkens".to_string())), + ("title".to_string(), Value::String("Baconeer".to_string())), + ])), + crate::Value::Dictionary(Context::from([ + ("first_name".to_string(), Value::String("Will".to_string())), + ("last_name".to_string(), Value::String("Power".to_string())), + ("title".to_string(), Value::String("CFO".to_string())), + ])), + crate::Value::Dictionary(Context::from([ + ("first_name".to_string(), Value::String("Justin".to_string())), + ("last_name".to_string(), Value::String("Time".to_string())), + ("title".to_string(), Value::String("CIO".to_string())), + ])), + ])), + ]); + match ct.render("index", &ctx) { + Ok(s) => println!("View result: {}", s ), + Err(e) => println!("Error: {:?}", e ), + } + } } -- cgit v1.2.3