mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 18:51:03 +01:00
8ab500bd6c
* Combine multiple `append`s into a single call * Remove unnecessary use of slice * Replace `strings.Index` with `strings.Contains` * Added .deepsource.toml config file for DeepSource integration
182 lines
3.9 KiB
Go
182 lines
3.9 KiB
Go
package internal
|
|
|
|
import (
|
|
"reflect"
|
|
"regexp"
|
|
"sort"
|
|
|
|
"golang.org/x/text/message/catalog"
|
|
)
|
|
|
|
// Var represents a message variable.
|
|
// The variables, like the sub messages are sorted.
|
|
// First: plurals (which again, are sorted)
|
|
// and then any custom keys.
|
|
// In variables, the sorting depends on the exact
|
|
// order the associated message uses the variables.
|
|
// This is extremely handy.
|
|
// This package requires the golang.org/x/text/message capabilities
|
|
// only for the variables feature, the message itself's pluralization is managed by the package.
|
|
type Var struct {
|
|
Name string // Variable name, e.g. Name
|
|
Literal string // Its literal is ${Name}
|
|
Cases []interface{} // one:...,few:...,...
|
|
Format string // defaults to "%d".
|
|
Argth int // 1, 2, 3...
|
|
}
|
|
|
|
func getVars(loc *Locale, key string, src map[string]interface{}) []Var {
|
|
if len(src) == 0 {
|
|
return nil
|
|
}
|
|
|
|
varsKey, ok := src[key]
|
|
if !ok {
|
|
return nil
|
|
}
|
|
|
|
varValue, ok := varsKey.([]interface{})
|
|
if !ok {
|
|
return nil
|
|
}
|
|
|
|
vars := make([]Var, 0, len(varValue))
|
|
|
|
for _, v := range varValue {
|
|
m, ok := v.(map[string]interface{})
|
|
if !ok {
|
|
continue
|
|
}
|
|
|
|
for k, inner := range m {
|
|
varFormat := "%d"
|
|
|
|
innerMap, ok := inner.(map[string]interface{})
|
|
if !ok {
|
|
continue
|
|
}
|
|
|
|
for kk, vv := range innerMap {
|
|
if kk == "format" {
|
|
if format, ok := vv.(string); ok {
|
|
varFormat = format
|
|
}
|
|
break
|
|
}
|
|
}
|
|
|
|
cases := getCases(loc, innerMap)
|
|
|
|
if len(cases) > 0 {
|
|
// cases = sortCases(cases)
|
|
vars = append(vars, Var{
|
|
Name: k,
|
|
Literal: "${" + k + "}",
|
|
Cases: cases,
|
|
Format: varFormat,
|
|
Argth: 1,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
delete(src, key) // delete the key after.
|
|
return vars
|
|
}
|
|
|
|
var unescapeVariableRegex = regexp.MustCompile("\\$\\{(.*?)}")
|
|
|
|
func sortVars(text string, vars []Var) (newVars []Var) {
|
|
argth := 1
|
|
for _, submatches := range unescapeVariableRegex.FindAllStringSubmatch(text, -1) {
|
|
name := submatches[1]
|
|
for _, variable := range vars {
|
|
if variable.Name == name {
|
|
variable.Argth = argth
|
|
newVars = append(newVars, variable)
|
|
argth++
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
sort.SliceStable(newVars, func(i, j int) bool {
|
|
return newVars[i].Argth < newVars[j].Argth
|
|
})
|
|
return
|
|
}
|
|
|
|
// it will panic if the incoming "elements" are not catmsg.Var (internal text package).
|
|
func removeVarsDuplicates(elements []Var) (result []Var) {
|
|
seen := make(map[string]struct{})
|
|
|
|
for v := range elements {
|
|
variable := elements[v]
|
|
name := variable.Name
|
|
if _, ok := seen[name]; !ok {
|
|
seen[name] = struct{}{}
|
|
result = append(result, variable)
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
func removeMsgVarsDuplicates(elements []catalog.Message) (result []catalog.Message) {
|
|
seen := make(map[string]struct{})
|
|
|
|
for _, elem := range elements {
|
|
val := reflect.Indirect(reflect.ValueOf(elem))
|
|
if val.Type().String() != "catmsg.Var" {
|
|
// keep.
|
|
result = append(result, elem)
|
|
continue // it's not a var.
|
|
}
|
|
name := val.FieldByName("Name").Interface().(string)
|
|
if _, ok := seen[name]; !ok {
|
|
seen[name] = struct{}{}
|
|
result = append(result, elem)
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func getCases(loc *Locale, src map[string]interface{}) []interface{} {
|
|
type PluralCase struct {
|
|
Form PluralForm
|
|
Value interface{}
|
|
}
|
|
|
|
pluralCases := make([]PluralCase, 0, len(src))
|
|
|
|
for key, value := range src {
|
|
form, ok := loc.Options.PluralFormDecoder(loc, key)
|
|
if !ok {
|
|
continue
|
|
}
|
|
|
|
pluralCases = append(pluralCases, PluralCase{
|
|
Form: form,
|
|
Value: value,
|
|
})
|
|
}
|
|
|
|
if len(pluralCases) == 0 {
|
|
return nil
|
|
}
|
|
|
|
sort.SliceStable(pluralCases, func(i, j int) bool {
|
|
left, right := pluralCases[i].Form, pluralCases[j].Form
|
|
return left.Less(right)
|
|
})
|
|
|
|
cases := make([]interface{}, 0, len(pluralCases)*2)
|
|
for _, pluralCase := range pluralCases {
|
|
// fmt.Printf("%s=%v\n", pluralCase.Form, pluralCase.Value)
|
|
cases = append(cases, pluralCase.Form.String(), pluralCase.Value)
|
|
}
|
|
|
|
return cases
|
|
}
|