-module(handles@internal@engine). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([eval/4, run/4]). -export_type([action/0]). -type action() :: {append, binary()} | {set_ctx, handles@ctx:value()} | {continue, list(handles@internal@parser:ast())} | {stop, handles@error:runtime_error()}. -spec eval( list(action()), handles@ctx:value(), gleam@dict:dict(binary(), list(handles@internal@parser:ast())), gleam@string_builder:string_builder() ) -> {ok, gleam@string_builder:string_builder()} | {error, handles@error:runtime_error()}. eval(Actions, Ctx, Partials, Builder) -> case Actions of [] -> {ok, Builder}; [{stop, Err}] -> {error, Err}; [{stop, Err@1} | _] -> {error, Err@1}; [{append, Value} | Rest_action] -> eval( Rest_action, Ctx, Partials, gleam@string_builder:append(Builder, Value) ); [{set_ctx, Ctx@1} | Rest_action@1] -> eval(Rest_action@1, Ctx@1, Partials, Builder); [{continue, []} | Rest_action@2] -> eval(Rest_action@2, Ctx, Partials, Builder); [{continue, [{constant, _, Value@1} | Rest_ast]} | Rest_action@3] -> eval( [{append, Value@1}, {continue, Rest_ast} | Rest_action@3], Ctx, Partials, Builder ); [{continue, [{property, Index, Path} | Rest_ast@1]} | Rest_action@4] -> case handles@internal@ctx_utils:get_property(Path, Ctx, Index) of {ok, Str} -> eval( [{append, Str}, {continue, Rest_ast@1} | Rest_action@4], Ctx, Partials, Builder ); {error, Err@2} -> eval([{stop, Err@2}], Ctx, Partials, Builder) end; [{continue, [{partial, Index@1, Id, Path@1} | Rest_ast@2]} | Rest_action@5] -> case gleam@dict:get(Partials, Id) of {error, _} -> eval( [{stop, {unknown_partial, Index@1, Id}}], Ctx, Partials, Builder ); {ok, Partial} -> case handles@internal@ctx_utils:get(Path@1, Ctx, Index@1) of {error, Err@3} -> eval([{stop, Err@3}], Ctx, Partials, Builder); {ok, New_ctx} -> eval( [{set_ctx, New_ctx}, {continue, Partial}, {set_ctx, Ctx}, {continue, Rest_ast@2} | Rest_action@5], Ctx, Partials, Builder ) end end; [{continue, [{if_block, Index@2, Path@2, Children} | Rest_ast@3]} | Rest_action@6] -> case handles@internal@ctx_utils:get_bool(Path@2, Ctx, Index@2) of {error, Err@4} -> eval([{stop, Err@4}], Ctx, Partials, Builder); {ok, false} -> eval( [{continue, Rest_ast@3} | Rest_action@6], Ctx, Partials, Builder ); {ok, true} -> eval( [{continue, Children}, {continue, Rest_ast@3} | Rest_action@6], Ctx, Partials, Builder ) end; [{continue, [{unless_block, Index@3, Path@3, Children@1} | Rest_ast@4]} | Rest_action@7] -> case handles@internal@ctx_utils:get_bool(Path@3, Ctx, Index@3) of {error, Err@5} -> eval([{stop, Err@5}], Ctx, Partials, Builder); {ok, true} -> eval( [{continue, Rest_ast@4} | Rest_action@7], Ctx, Partials, Builder ); {ok, false} -> eval( [{continue, Children@1}, {continue, Rest_ast@4} | Rest_action@7], Ctx, Partials, Builder ) end; [{continue, [{each_block, Index@4, Path@4, Children@2} | Rest_ast@5]} | Rest_action@8] -> case handles@internal@ctx_utils:get_list(Path@4, Ctx, Index@4) of {error, Err@6} -> eval([{stop, Err@6}], Ctx, Partials, Builder); {ok, []} -> eval( [{continue, Rest_ast@5} | Rest_action@8], Ctx, Partials, Builder ); {ok, Ctxs} -> eval( begin _pipe = Ctxs, _pipe@1 = gleam@list:flat_map( _pipe, fun(New_ctx@1) -> [{set_ctx, New_ctx@1}, {continue, Children@2}, {set_ctx, Ctx}] end ), lists:append( _pipe@1, [{continue, Rest_ast@5} | Rest_action@8] ) end, Ctx, Partials, Builder ) end end. -spec run( list(handles@internal@parser:ast()), handles@ctx:value(), gleam@dict:dict(binary(), list(handles@internal@parser:ast())), gleam@string_builder:string_builder() ) -> {ok, gleam@string_builder:string_builder()} | {error, handles@error:runtime_error()}. run(Ast, Ctx, Partials, Builder) -> eval([{continue, Ast}], Ctx, Partials, Builder).