diff --git a/service.go b/service.go index 8295646..cf871ce 100644 --- a/service.go +++ b/service.go @@ -5,6 +5,7 @@ import ( "io/fs" "maps" "path" + "reflect" "slices" "sync" "sync/atomic" @@ -55,7 +56,14 @@ func WithHandlers(handlers ...KeyHandler) Option { // WithDefaultHandlers adds the default i18n.* namespace handlers. func WithDefaultHandlers() Option { - return func(s *Service) { s.handlers = append(s.handlers, DefaultHandlers()...) } + return func(s *Service) { + for _, handler := range DefaultHandlers() { + if hasHandlerType(s.handlers, handler) { + continue + } + s.handlers = append(s.handlers, handler) + } + } } // WithMode sets the translation mode. @@ -713,3 +721,13 @@ func (s *Service) autoDetectLanguage() { s.currentLang = detected } } + +func hasHandlerType(handlers []KeyHandler, candidate KeyHandler) bool { + want := reflect.TypeOf(candidate) + for _, handler := range handlers { + if reflect.TypeOf(handler) == want { + return true + } + } + return false +} diff --git a/service_test.go b/service_test.go index 3dbb536..94f915b 100644 --- a/service_test.go +++ b/service_test.go @@ -412,6 +412,17 @@ func TestServiceHandlers(t *testing.T) { } } +func TestWithDefaultHandlers_Idempotent(t *testing.T) { + svc, err := New(WithDefaultHandlers()) + if err != nil { + t.Fatalf("New() with WithDefaultHandlers() failed: %v", err) + } + + if got := len(svc.Handlers()); got != 6 { + t.Fatalf("len(Handlers()) = %d, want 6", got) + } +} + func TestServiceWithOptions(t *testing.T) { svc, err := New( WithFallback("en"),