Files
RenewCMS/internal/domain/language/languageDomain.go
T

91 lines
2.0 KiB
Go

package language
import (
"errors"
"regexp"
"slices"
"strings"
)
var (
ErrInvalidLanguage = errors.New("invalid language tag")
ErrUnsupportedLanguage = errors.New("unsupported language")
ErrNoDefaultLanguage = errors.New("the site has no default language")
)
const (
Unassigned = ""
MaxTagLength = 35
)
var supported = []string{"en", "en-GB", "en-US", "fr", "fr-CA", "pt", "pt-BR", "es", "de", "ar"}
var tagPattern = regexp.MustCompile(`^([A-Za-z]{2,3})(?:-([A-Za-z]{2}))?$`)
func Supported() []string {
return slices.Clone(supported)
}
func Normalize(tag string) (string, error) {
parts := tagPattern.FindStringSubmatch(strings.TrimSpace(tag))
if parts == nil {
return "", ErrInvalidLanguage
}
normalized := strings.ToLower(parts[1])
if parts[2] != "" {
normalized += "-" + strings.ToUpper(parts[2])
}
if !slices.Contains(supported, normalized) {
return "", ErrUnsupportedLanguage
}
return normalized, nil
}
type Suggestion struct {
Tag string
Found bool
Substituted bool
}
func Suggest(locale *string) Suggestion {
if locale == nil {
return Suggestion{}
}
tag, err := Normalize(*locale)
if err == nil {
return Suggestion{Tag: tag, Found: true}
}
if !errors.Is(err, ErrUnsupportedLanguage) {
return Suggestion{}
}
base, _, _ := strings.Cut(strings.TrimSpace(*locale), "-")
if fallback, err := Normalize(base); err == nil {
return Suggestion{Tag: fallback, Found: true, Substituted: true}
}
return Suggestion{}
}
type SiteLanguage struct {
SiteID uint32
Tag string
IsDefault bool
Enabled bool
Confirmed bool
}
func DefaultOf(languages []SiteLanguage) (SiteLanguage, bool) {
index := slices.IndexFunc(languages, func(candidate SiteLanguage) bool { return candidate.IsDefault })
if index < 0 {
return SiteLanguage{}, false
}
return languages[index], true
}
func StartingTag(languages []SiteLanguage) string {
defaultLanguage, found := DefaultOf(languages)
if !found || !defaultLanguage.Confirmed {
return Unassigned
}
return defaultLanguage.Tag
}