From 6758585c3617fa237c6f0863ca2e362bafc83891 Mon Sep 17 00:00:00 2001 From: Virgil Date: Thu, 2 Apr 2026 02:58:46 +0000 Subject: [PATCH] feat(i18n): accept structured handler args Co-Authored-By: Virgil --- handler.go | 29 +++++++++++++++++++++++++++++ handler_test.go | 20 ++++++++++++++++++++ transform.go | 17 +++++++++++++++++ 3 files changed, 66 insertions(+) diff --git a/handler.go b/handler.go index 50e46ca..c1fb65f 100644 --- a/handler.go +++ b/handler.go @@ -223,6 +223,21 @@ func subjectArgText(arg any) string { return "" } return v.String() + case *TranslationContext: + if v == nil { + return "" + } + if text := core.Trim(v.String()); text != "" { + return text + } + if v.Extra != nil { + if text := contextArgText(v.Extra); text != "" { + return text + } + } + return "" + case map[string]any: + return contextArgText(v) case fmt.Stringer: return v.String() default: @@ -230,6 +245,20 @@ func subjectArgText(arg any) string { } } +func contextArgText(values map[string]any) string { + if len(values) == 0 { + return "" + } + for _, key := range []string{"Subject", "subject", "Value", "value", "Text", "text", "Context", "context", "Noun", "noun"} { + if raw, ok := values[key]; ok { + if text := core.Trim(core.Sprintf("%v", raw)); text != "" { + return text + } + } + } + return "" +} + // RunHandlerChain executes a chain of handlers for a key. func RunHandlerChain(handlers []KeyHandler, key string, args []any, fallback func() string) string { for i, h := range handlers { diff --git a/handler_test.go b/handler_test.go index 51fa744..aba4496 100644 --- a/handler_test.go +++ b/handler_test.go @@ -58,6 +58,11 @@ func TestProgressHandler(t *testing.T) { if got != "Building project..." { t.Errorf("ProgressHandler.Handle(build, TranslationContext) = %q, want %q", got, "Building project...") } + + got = h.Handle("i18n.progress.build", []any{map[string]any{"Subject": "project"}}, nil) + if got != "Building project..." { + t.Errorf("ProgressHandler.Handle(build, map[Subject:project]) = %q, want %q", got, "Building project...") + } } func TestCountHandler(t *testing.T) { @@ -102,6 +107,11 @@ func TestCountHandler(t *testing.T) { if got != "3 files" { t.Errorf("CountHandler.Handle(file, Subject.Count(3)) = %q, want %q", got, "3 files") } + + got = h.Handle("i18n.count.file", []any{C("file").Set("Count", 3)}, nil) + if got != "3 files" { + t.Errorf("CountHandler.Handle(file, TranslationContext.Count=3) = %q, want %q", got, "3 files") + } } func TestDoneHandler(t *testing.T) { @@ -133,6 +143,11 @@ func TestDoneHandler(t *testing.T) { t.Errorf("DoneHandler.Handle(delete, TranslationContext) = %q, want %q", got, "Config.yaml deleted") } + got = h.Handle("i18n.done.delete", []any{map[string]any{"Subject": "config.yaml"}}, nil) + if got != "Config.yaml deleted" { + t.Errorf("DoneHandler.Handle(delete, map[Subject:config.yaml]) = %q, want %q", got, "Config.yaml deleted") + } + // Without subject — just past tense got = h.Handle("i18n.done.delete", nil, nil) if got != "Deleted" { @@ -162,6 +177,11 @@ func TestFailHandler(t *testing.T) { t.Errorf("FailHandler.Handle(push, TranslationContext) = %q, want %q", got, "Failed to push commits") } + got = h.Handle("i18n.fail.push", []any{map[string]any{"Subject": "commits"}}, nil) + if got != "Failed to push commits" { + t.Errorf("FailHandler.Handle(push, map[Subject:commits]) = %q, want %q", got, "Failed to push commits") + } + got = h.Handle("i18n.fail.push", nil, nil) if got != "Failed to push" { t.Errorf("FailHandler.Handle(push) = %q, want %q", got, "Failed to push") diff --git a/transform.go b/transform.go index 10fecaf..c526913 100644 --- a/transform.go +++ b/transform.go @@ -10,14 +10,31 @@ func getCount(data any) int { return 0 } return d.CountInt() + case *TranslationContext: + if d == nil || d.Extra == nil { + return 0 + } + if c, ok := d.Extra["Count"]; ok { + return toInt(c) + } + if c, ok := d.Extra["count"]; ok { + return toInt(c) + } + return 0 case map[string]any: if c, ok := d["Count"]; ok { return toInt(c) } + if c, ok := d["count"]; ok { + return toInt(c) + } case map[string]int: if c, ok := d["Count"]; ok { return c } + if c, ok := d["count"]; ok { + return c + } } return toInt(data) } -- 2.45.3