Path: blob/main/vendor/golang.org/x/text/language/coverage.go
2880 views
// Copyright 2014 The Go Authors. All rights reserved.1// Use of this source code is governed by a BSD-style2// license that can be found in the LICENSE file.34package language56import (7"fmt"8"sort"910"golang.org/x/text/internal/language"11)1213// The Coverage interface is used to define the level of coverage of an14// internationalization service. Note that not all types are supported by all15// services. As lists may be generated on the fly, it is recommended that users16// of a Coverage cache the results.17type Coverage interface {18// Tags returns the list of supported tags.19Tags() []Tag2021// BaseLanguages returns the list of supported base languages.22BaseLanguages() []Base2324// Scripts returns the list of supported scripts.25Scripts() []Script2627// Regions returns the list of supported regions.28Regions() []Region29}3031var (32// Supported defines a Coverage that lists all supported subtags. Tags33// always returns nil.34Supported Coverage = allSubtags{}35)3637// TODO:38// - Support Variants, numbering systems.39// - CLDR coverage levels.40// - Set of common tags defined in this package.4142type allSubtags struct{}4344// Regions returns the list of supported regions. As all regions are in a45// consecutive range, it simply returns a slice of numbers in increasing order.46// The "undefined" region is not returned.47func (s allSubtags) Regions() []Region {48reg := make([]Region, language.NumRegions)49for i := range reg {50reg[i] = Region{language.Region(i + 1)}51}52return reg53}5455// Scripts returns the list of supported scripts. As all scripts are in a56// consecutive range, it simply returns a slice of numbers in increasing order.57// The "undefined" script is not returned.58func (s allSubtags) Scripts() []Script {59scr := make([]Script, language.NumScripts)60for i := range scr {61scr[i] = Script{language.Script(i + 1)}62}63return scr64}6566// BaseLanguages returns the list of all supported base languages. It generates67// the list by traversing the internal structures.68func (s allSubtags) BaseLanguages() []Base {69bs := language.BaseLanguages()70base := make([]Base, len(bs))71for i, b := range bs {72base[i] = Base{b}73}74return base75}7677// Tags always returns nil.78func (s allSubtags) Tags() []Tag {79return nil80}8182// coverage is used by NewCoverage which is used as a convenient way for83// creating Coverage implementations for partially defined data. Very often a84// package will only need to define a subset of slices. coverage provides a85// convenient way to do this. Moreover, packages using NewCoverage, instead of86// their own implementation, will not break if later new slice types are added.87type coverage struct {88tags func() []Tag89bases func() []Base90scripts func() []Script91regions func() []Region92}9394func (s *coverage) Tags() []Tag {95if s.tags == nil {96return nil97}98return s.tags()99}100101// bases implements sort.Interface and is used to sort base languages.102type bases []Base103104func (b bases) Len() int {105return len(b)106}107108func (b bases) Swap(i, j int) {109b[i], b[j] = b[j], b[i]110}111112func (b bases) Less(i, j int) bool {113return b[i].langID < b[j].langID114}115116// BaseLanguages returns the result from calling s.bases if it is specified or117// otherwise derives the set of supported base languages from tags.118func (s *coverage) BaseLanguages() []Base {119if s.bases == nil {120tags := s.Tags()121if len(tags) == 0 {122return nil123}124a := make([]Base, len(tags))125for i, t := range tags {126a[i] = Base{language.Language(t.lang())}127}128sort.Sort(bases(a))129k := 0130for i := 1; i < len(a); i++ {131if a[k] != a[i] {132k++133a[k] = a[i]134}135}136return a[:k+1]137}138return s.bases()139}140141func (s *coverage) Scripts() []Script {142if s.scripts == nil {143return nil144}145return s.scripts()146}147148func (s *coverage) Regions() []Region {149if s.regions == nil {150return nil151}152return s.regions()153}154155// NewCoverage returns a Coverage for the given lists. It is typically used by156// packages providing internationalization services to define their level of157// coverage. A list may be of type []T or func() []T, where T is either Tag,158// Base, Script or Region. The returned Coverage derives the value for Bases159// from Tags if no func or slice for []Base is specified. For other unspecified160// types the returned Coverage will return nil for the respective methods.161func NewCoverage(list ...interface{}) Coverage {162s := &coverage{}163for _, x := range list {164switch v := x.(type) {165case func() []Base:166s.bases = v167case func() []Script:168s.scripts = v169case func() []Region:170s.regions = v171case func() []Tag:172s.tags = v173case []Base:174s.bases = func() []Base { return v }175case []Script:176s.scripts = func() []Script { return v }177case []Region:178s.regions = func() []Region { return v }179case []Tag:180s.tags = func() []Tag { return v }181default:182panic(fmt.Sprintf("language: unsupported set type %T", v))183}184}185return s186}187188189