@@ -28,6 +28,10 @@ fn eval_statement(stmt: &Statement, value: &Value) -> error::Result<Value> {
2828 Statement :: Nest { paths, target, .. } => eval_nest ( value, paths, target) ,
2929 Statement :: Where { condition, .. } => eval_where ( value, condition) ,
3030 Statement :: Sort { keys, .. } => eval_sort ( value, keys) ,
31+ Statement :: Each { path, body, .. } => eval_each ( value, path, body) ,
32+ Statement :: When {
33+ condition, body, ..
34+ } => eval_when ( value, condition, body) ,
3135 }
3236}
3337
@@ -334,6 +338,48 @@ fn eval_sort(value: &Value, keys: &[SortKey]) -> error::Result<Value> {
334338 }
335339}
336340
341+ // ---------------------------------------------------------------------------
342+ // each
343+ // ---------------------------------------------------------------------------
344+
345+ fn eval_each ( value : & Value , path : & Path , body : & [ Statement ] ) -> error:: Result < Value > {
346+ let target = resolve_path ( value, & path. segments ) ;
347+ match target {
348+ Some ( Value :: Array ( arr) ) => {
349+ let mut updated = Vec :: with_capacity ( arr. len ( ) ) ;
350+ for item in & arr {
351+ let mut result = item. clone ( ) ;
352+ for stmt in body {
353+ result = eval_statement ( stmt, & result) ?;
354+ }
355+ updated. push ( result) ;
356+ }
357+ Ok ( set_path ( value, & path. segments , Value :: Array ( updated) ) )
358+ }
359+ Some ( _) => Err ( error:: MorphError :: mapping ( "each requires an array target" ) ) ,
360+ None => Err ( error:: MorphError :: mapping (
361+ "each target path does not exist" ,
362+ ) ) ,
363+ }
364+ }
365+
366+ // ---------------------------------------------------------------------------
367+ // when
368+ // ---------------------------------------------------------------------------
369+
370+ fn eval_when ( value : & Value , condition : & Expr , body : & [ Statement ] ) -> error:: Result < Value > {
371+ let cond_result = eval_expr ( condition, value) ?;
372+ if is_truthy ( & cond_result) {
373+ let mut result = value. clone ( ) ;
374+ for stmt in body {
375+ result = eval_statement ( stmt, & result) ?;
376+ }
377+ Ok ( result)
378+ } else {
379+ Ok ( value. clone ( ) )
380+ }
381+ }
382+
337383// ---------------------------------------------------------------------------
338384// Expression evaluation
339385// ---------------------------------------------------------------------------
0 commit comments