From 4560014954522960a82a3ca5a9d8b410ade4927a Mon Sep 17 00:00:00 2001 From: Spencer Brower <6729162+sbrow@users.noreply.github.com> Date: Thu, 23 Jul 2026 11:38:17 -0400 Subject: [PATCH] feat: Pipes now have access to the full template context. --- mustache/mustache.odin | 9 +++++---- mustache/pipes.odin | 25 +++++++++++++++---------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/mustache/mustache.odin b/mustache/mustache.odin index 953b669..a306c53 100644 --- a/mustache/mustache.odin +++ b/mustache/mustache.odin @@ -2,6 +2,7 @@ package mustache import "core:fmt" import "core:log" +import "core:reflect" import "core:strings" // --------------------------------------------------------------------------- @@ -556,7 +557,7 @@ render_nodes :: proc( warn_unknown_key(current, ctx[:], node) } if len(node.filters) > 0 { - transformed, perr := apply_pipeline(val, node.filters[:], node.pos) + transformed, perr := apply_pipeline(val, node.filters[:], node.pos, ctx[:]) if perr != nil { return perr } @@ -598,7 +599,7 @@ render_nodes :: proc( warn_unknown_key(current, ctx[:], node) } if len(node.filters) > 0 { - transformed, perr := apply_pipeline(val, node.filters[:], node.pos) + transformed, perr := apply_pipeline(val, node.filters[:], node.pos, ctx[:]) if perr != nil { return perr } @@ -636,7 +637,7 @@ render_nodes :: proc( warn_unknown_key(current, ctx[:], node) } if len(node.filters) > 0 { - transformed, perr := apply_pipeline(val, node.filters[:], node.pos) + transformed, perr := apply_pipeline(val, node.filters[:], node.pos, ctx[:]) if perr != nil { return perr } @@ -692,7 +693,7 @@ render_nodes :: proc( warn_unknown_key(current, ctx[:], node) } if len(node.filters) > 0 { - transformed, perr := apply_pipeline(val, node.filters[:], node.pos) + transformed, perr := apply_pipeline(val, node.filters[:], node.pos, ctx[:]) if perr != nil { return perr } diff --git a/mustache/pipes.odin b/mustache/pipes.odin index 592532c..9f708cd 100644 --- a/mustache/pipes.odin +++ b/mustache/pipes.odin @@ -99,26 +99,31 @@ parse_pipeline :: proc( return key, nil } -apply_pipeline :: proc(value: any, filters: []Pipe_Filter, pos: int) -> (any, Error) { - current := value +apply_pipeline :: proc( + value: any, + filters: []Pipe_Filter, + pos: int, + ctx: []any, +) -> ( + current: any, + err: Error, +) { + current = value for &filter in filters { - result, err := apply_filter(current, &filter, pos) - if err != nil { - return nil, err - } - current = result + current = apply_filter(current, &filter, pos, ctx) or_return } - return current, nil + return } -apply_filter :: proc(value: any, filter: ^Pipe_Filter, pos: int) -> (any, Error) { +// TODO: diagnostics don't show anything relevent +apply_filter :: proc(value: any, filter: ^Pipe_Filter, pos: int, ctx: []any) -> (any, Error) { switch filter.op { case "group_by": return apply_group_by(value, filter.args[:], pos) case "format": str, ok := reflect.as_string(value) if !ok { - return value, Error_Body{ + return value, Error_Body { msg = "format may only be used on dates", pos = pos, kind = .Data,