66 lines
1.4 KiB
Go
66 lines
1.4 KiB
Go
package language
|
|
|
|
import (
|
|
"errors"
|
|
"regexp"
|
|
"slices"
|
|
"strings"
|
|
)
|
|
|
|
var (
|
|
ErrInvalidLanguage = errors.New("invalid language tag")
|
|
ErrUnsupportedLanguage = errors.New("unsupported 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{}
|
|
}
|