62 lines
1.6 KiB
Go
62 lines
1.6 KiB
Go
// Package lang canonicalizes ISO 639 language codes and ISO 3166-1 country
|
|
// codes at ingest write sites so equivalent values ("en"/"eng"/"ENG")
|
|
// collapse to a single stored form.
|
|
package lang
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"golang.org/x/text/language"
|
|
)
|
|
|
|
// Canonical returns the ISO 639-1 lowercase 2-letter form of value, or the
|
|
// 3-letter form for languages without a 2-letter equivalent (e.g. "fil").
|
|
// Unparseable inputs are returned trimmed and lowercased verbatim so we
|
|
// never silently drop data.
|
|
func Canonical(value string) string {
|
|
trimmed := strings.ToLower(strings.TrimSpace(value))
|
|
if trimmed == "" {
|
|
return ""
|
|
}
|
|
tag, err := language.Parse(trimmed)
|
|
if err != nil {
|
|
return trimmed
|
|
}
|
|
base, conf := tag.Base()
|
|
if conf == language.No {
|
|
return trimmed
|
|
}
|
|
return strings.ToLower(base.String())
|
|
}
|
|
|
|
// CanonicalCountry returns the ISO 3166-1 alpha-2 uppercase form. Unparseable
|
|
// inputs are returned trimmed and uppercased verbatim.
|
|
func CanonicalCountry(value string) string {
|
|
trimmed := strings.ToUpper(strings.TrimSpace(value))
|
|
if trimmed == "" {
|
|
return ""
|
|
}
|
|
region, err := language.ParseRegion(trimmed)
|
|
if err != nil {
|
|
return trimmed
|
|
}
|
|
return region.String()
|
|
}
|
|
|
|
// CanonicalCountries returns a copy of values with each entry canonicalized
|
|
// and empties dropped. Preserves nil so callers can keep the SQL NULL
|
|
// distinction from an empty array.
|
|
func CanonicalCountries(values []string) []string {
|
|
if values == nil {
|
|
return nil
|
|
}
|
|
out := make([]string, 0, len(values))
|
|
for _, v := range values {
|
|
c := CanonicalCountry(v)
|
|
if c != "" {
|
|
out = append(out, c)
|
|
}
|
|
}
|
|
return out
|
|
}
|