96 lines
2.7 KiB
Go
96 lines
2.7 KiB
Go
package localization
|
|
|
|
import (
|
|
"RenewCMS/internal/domain/language"
|
|
"regexp"
|
|
"slices"
|
|
"strings"
|
|
)
|
|
|
|
var socialLocalePattern = regexp.MustCompile(`^([A-Za-z]{2,3})_([A-Za-z]{2})$`)
|
|
|
|
func NormalizeSocialLocale(tag string, social *string) (*string, error) {
|
|
if social == nil {
|
|
return nil, nil
|
|
}
|
|
parts := socialLocalePattern.FindStringSubmatch(*social)
|
|
if parts == nil {
|
|
return nil, ErrInvalidSocialLocale
|
|
}
|
|
tagLanguage, _, _ := strings.Cut(tag, "-")
|
|
if !strings.EqualFold(parts[1], tagLanguage) {
|
|
return nil, ErrInvalidSocialLocale
|
|
}
|
|
normalized := strings.ToLower(parts[1]) + "_" + strings.ToUpper(parts[2])
|
|
return &normalized, nil
|
|
}
|
|
|
|
func SocialLocaleState(row Row) string {
|
|
if row.SocialLocale != nil {
|
|
return SocialLocaleSet
|
|
}
|
|
if _, region, found := strings.Cut(row.Tag, "-"); found && region != "" {
|
|
return SocialLocaleDerived
|
|
}
|
|
return SocialLocaleNotSet
|
|
}
|
|
|
|
func EffectiveSocialLocale(row Row) *string {
|
|
switch SocialLocaleState(row) {
|
|
case SocialLocaleSet:
|
|
return row.SocialLocale
|
|
case SocialLocaleDerived:
|
|
derived := strings.Replace(row.Tag, "-", "_", 1)
|
|
return &derived
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func normalizeEntries(entries []Entry) ([]Entry, error) {
|
|
normalized := make([]Entry, 0, len(entries))
|
|
seen := map[string]bool{}
|
|
for _, entry := range entries {
|
|
tag, err := language.Normalize(entry.Tag)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if seen[tag] {
|
|
return nil, ErrDuplicateLanguage
|
|
}
|
|
seen[tag] = true
|
|
social, err := NormalizeSocialLocale(tag, entry.SocialLocale)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
normalized = append(normalized, Entry{Tag: tag, Enabled: entry.Enabled, SocialLocale: social})
|
|
}
|
|
return normalized, nil
|
|
}
|
|
|
|
func Plan(current []Row, counts map[string]VersionCount, change Change) ([]Row, error) {
|
|
entries, err := normalizeEntries(change.Languages)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if !slices.ContainsFunc(entries, func(entry Entry) bool { return entry.Enabled }) {
|
|
return nil, ErrNoEnabledLanguage
|
|
}
|
|
defaultTag, err := language.Normalize(change.Default)
|
|
if err != nil || !slices.ContainsFunc(entries, func(entry Entry) bool { return entry.Tag == defaultTag && entry.Enabled }) {
|
|
return nil, ErrDefaultNotEnabled
|
|
}
|
|
confirmed := map[string]bool{}
|
|
for _, row := range current {
|
|
confirmed[row.Tag] = row.Confirmed
|
|
if !slices.ContainsFunc(entries, func(entry Entry) bool { return entry.Tag == row.Tag }) && counts[row.Tag].Total+counts[row.Tag].Trashed > 0 {
|
|
return nil, ErrLanguageInUse
|
|
}
|
|
}
|
|
next := make([]Row, 0, len(entries))
|
|
for _, entry := range entries {
|
|
isDefault := entry.Tag == defaultTag
|
|
next = append(next, Row{Tag: entry.Tag, IsDefault: isDefault, Enabled: entry.Enabled, Confirmed: confirmed[entry.Tag] || isDefault, SocialLocale: entry.SocialLocale})
|
|
}
|
|
return next, nil
|
|
}
|