forkjo/modules/translation/i18n/dummy.go

66 lines
1.7 KiB
Go

// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package i18n
import (
"fmt"
"html/template"
"reflect"
"slices"
"strings"
)
type KeyLocale struct{}
var _ Locale = (*KeyLocale)(nil)
// HasKey implements Locale.
func (k *KeyLocale) HasKey(trKey string) bool {
return true
}
// TrHTML implements Locale.
func (k *KeyLocale) TrHTML(trKey string, trArgs ...any) template.HTML {
args := slices.Clone(trArgs)
for i, v := range args {
switch v := v.(type) {
case nil, bool, int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, template.HTML:
// for most basic types (including template.HTML which is safe), just do nothing and use it
case string:
args[i] = template.HTMLEscapeString(v)
case fmt.Stringer:
args[i] = template.HTMLEscapeString(v.String())
default:
args[i] = template.HTMLEscapeString(fmt.Sprint(v))
}
}
return template.HTML(k.TrString(trKey, args...))
}
// TrString implements Locale.
func (k *KeyLocale) TrString(trKey string, trArgs ...any) string {
return FormatDummy(trKey, trArgs...)
}
func FormatDummy(trKey string, args ...any) string {
if len(args) == 0 {
return fmt.Sprintf("(%s)", trKey)
}
fmtArgs := make([]any, 0, len(args)+1)
fmtArgs = append(fmtArgs, trKey)
for _, arg := range args {
val := reflect.ValueOf(arg)
if val.Kind() == reflect.Slice {
for i := 0; i < val.Len(); i++ {
fmtArgs = append(fmtArgs, val.Index(i).Interface())
}
} else {
fmtArgs = append(fmtArgs, arg)
}
}
template := fmt.Sprintf("(%%s: %s)", strings.Join(slices.Repeat([]string{"%v"}, len(fmtArgs)-1), ", "))
return fmt.Sprintf(template, fmtArgs...)
}