149 lines
4.1 KiB
Go
149 lines
4.1 KiB
Go
package schema
|
|
|
|
import (
|
|
"strings"
|
|
"sync"
|
|
|
|
"aego/engine/i18n"
|
|
)
|
|
|
|
// Catalog keys of the schema texts (D348): schema.<type>, schema.<type>.doc, schema.<type>.<field>, schema.<type>.<field>.doc, enum.<enum>.<value>.
|
|
|
|
type typeKeys struct{ title, doc, en string }
|
|
|
|
type fieldKeys struct{ label, doc, en string }
|
|
|
|
var (
|
|
typeKeyCache sync.Map
|
|
fieldKeyCache sync.Map
|
|
enumKeyCache sync.Map
|
|
)
|
|
|
|
func keysOfType(td *TypeDescriptor) *typeKeys {
|
|
if k, ok := typeKeyCache.Load(td); ok {
|
|
return k.(*typeKeys)
|
|
}
|
|
k := &typeKeys{title: TypeKey(td), doc: TypeKey(td) + ".doc", en: EnglishTitle(td)}
|
|
typeKeyCache.Store(td, k)
|
|
return k
|
|
}
|
|
|
|
func keysOfField(td *TypeDescriptor, fd *FieldDescriptor) *fieldKeys {
|
|
if k, ok := fieldKeyCache.Load(fd); ok {
|
|
return k.(*fieldKeys)
|
|
}
|
|
k := &fieldKeys{label: FieldKey(td, fd), doc: FieldKey(td, fd) + ".doc", en: Label(fd)}
|
|
fieldKeyCache.Store(fd, k)
|
|
return k
|
|
}
|
|
|
|
// TypeKey is the catalog key of a type's display name.
|
|
func TypeKey(td *TypeDescriptor) string { return "schema." + td.FullName }
|
|
|
|
// FieldKey is the catalog key of a field's label.
|
|
func FieldKey(td *TypeDescriptor, fd *FieldDescriptor) string {
|
|
return "schema." + td.FullName + "." + fd.Name
|
|
}
|
|
|
|
// EnumKey is the catalog key of an enum value's label.
|
|
func EnumKey(enum, value string) string { return "enum." + enum + "." + value }
|
|
|
|
// Title is EnglishTitle in the current language.
|
|
func Title(td *TypeDescriptor) string {
|
|
if td.Kind == TypeScript {
|
|
return EnglishTitle(td)
|
|
}
|
|
k := keysOfType(td)
|
|
return i18n.Lookup(k.title, k.en)
|
|
}
|
|
|
|
// EnglishTitle is a type's DisplayName, else the humanized last part of its name.
|
|
func EnglishTitle(td *TypeDescriptor) string {
|
|
if td.DisplayName != "" {
|
|
return td.DisplayName
|
|
}
|
|
return Humanize(td.FullName[strings.LastIndexByte(td.FullName, '.')+1:])
|
|
}
|
|
|
|
// SearchNames is shared by the editor creation palette and documentation.
|
|
// Technical IDs, all shipped translations and former display names remain
|
|
// searchable regardless of the active UI language.
|
|
func SearchNames(td *TypeDescriptor) []string {
|
|
names := []string{td.FullName, EnglishTitle(td)}
|
|
names = append(names, td.SearchAliases...)
|
|
names = append(names, i18n.Default().Translations(TypeKey(td))...)
|
|
out := make([]string, 0, len(names))
|
|
seen := make(map[string]bool, len(names))
|
|
for _, name := range names {
|
|
name = strings.TrimSpace(name)
|
|
key := strings.ToLower(name)
|
|
if key != "" && !seen[key] {
|
|
seen[key] = true
|
|
out = append(out, name)
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
// TypeDoc is a type's description in the current language.
|
|
func TypeDoc(td *TypeDescriptor) string {
|
|
if td.Doc == "" || td.Kind == TypeScript {
|
|
return td.Doc
|
|
}
|
|
return i18n.Lookup(keysOfType(td).doc, td.Doc)
|
|
}
|
|
|
|
// FieldLabel is Label in the current language.
|
|
func FieldLabel(td *TypeDescriptor, fd *FieldDescriptor) string {
|
|
if td.Kind == TypeScript {
|
|
return Label(fd)
|
|
}
|
|
k := keysOfField(td, fd)
|
|
return i18n.Lookup(k.label, k.en)
|
|
}
|
|
|
|
// FieldHelp is a field's description in the current language.
|
|
func FieldHelp(td *TypeDescriptor, fd *FieldDescriptor) string {
|
|
if fd.Doc == "" || td.Kind == TypeScript {
|
|
return fd.Doc
|
|
}
|
|
return i18n.Lookup(keysOfField(td, fd).doc, fd.Doc)
|
|
}
|
|
|
|
// EnumLabel is the label of the i-th enum value of a field; English shows the value's name.
|
|
func EnumLabel(fd *FieldDescriptor, i int) string {
|
|
if fd.EnumName == "" {
|
|
return fd.Enum[i].Name
|
|
}
|
|
var keys []string
|
|
if k, ok := enumKeyCache.Load(fd); ok {
|
|
keys = k.([]string)
|
|
} else {
|
|
for _, ev := range fd.Enum {
|
|
keys = append(keys, EnumKey(fd.EnumName, ev.Name))
|
|
}
|
|
enumKeyCache.Store(fd, keys)
|
|
}
|
|
return i18n.Lookup(keys[i], fd.Enum[i].Name)
|
|
}
|
|
|
|
// FieldTip is the field's tooltip: its description in the current language, or a tooltip set apart from it.
|
|
func FieldTip(td *TypeDescriptor, fd *FieldDescriptor) string {
|
|
if fd.Hints.Tooltip == fd.Doc {
|
|
return FieldHelp(td, fd)
|
|
}
|
|
return fd.Hints.Tooltip
|
|
}
|
|
|
|
var categoryKeys sync.Map
|
|
|
|
// CategoryLabel is a field category, such as Runtime, in the current language.
|
|
func CategoryLabel(c string) string {
|
|
k, ok := categoryKeys.Load(c)
|
|
if !ok {
|
|
k = "schema.category." + c
|
|
categoryKeys.Store(c, k)
|
|
}
|
|
return i18n.Lookup(k.(string), c)
|
|
}
|