github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/text/internal/match.go (about)

     1  // Copyright 2015 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package internal
     6  
     7  // This file contains matchers that implement CLDR inheritance.
     8  //
     9  //     See http://unicode.org/reports/tr35/#Locale_Inheritance.
    10  //
    11  // Some of the inheritance described in this document is already handled by
    12  // the cldr package.
    13  
    14  import (
    15  	"golang.org/x/text/language"
    16  )
    17  
    18  // TODO: consider if (some of the) matching algorithm needs to be public after
    19  // getting some feel about what is generic and what is specific.
    20  
    21  // NewInheritanceMatcher returns a matcher that matches based on the inheritance
    22  // chain.
    23  //
    24  // The matcher uses canonicalization and the parent relationship to find a
    25  // match. The resulting match will always be either Und or a language with the
    26  // same language and script as the requested language. It will not match
    27  // languages for which there is understood to be mutual or one-directional
    28  // intelligibility.
    29  //
    30  // A Match will indicate an Exact match if the language matches after
    31  // canonicalization and High if the matched tag is a parent.
    32  func NewInheritanceMatcher(t []language.Tag) language.Matcher {
    33  	tags := make(inheritanceMatcher)
    34  	for i, tag := range t {
    35  		ct, err := language.All.Canonicalize(tag)
    36  		if err != nil {
    37  			ct = tag
    38  		}
    39  		tags[ct] = i
    40  	}
    41  	return tags
    42  }
    43  
    44  type inheritanceMatcher map[language.Tag]int
    45  
    46  func (m inheritanceMatcher) Match(want ...language.Tag) (language.Tag, int, language.Confidence) {
    47  	for _, t := range want {
    48  		ct, err := language.All.Canonicalize(t)
    49  		if err != nil {
    50  			ct = t
    51  		}
    52  		conf := language.Exact
    53  		for {
    54  			if index, ok := m[ct]; ok {
    55  				return ct, index, conf
    56  			}
    57  			if ct == language.Und {
    58  				break
    59  			}
    60  			ct = ct.Parent()
    61  			conf = language.High
    62  		}
    63  	}
    64  	return language.Und, 0, language.No
    65  }