| // Copyright 2015 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| package internal | |
| // This file contains matchers that implement CLDR inheritance. | |
| // | |
| // See http://unicode.org/reports/tr35/#Locale_Inheritance. | |
| // | |
| // Some of the inheritance described in this document is already handled by | |
| // the cldr package. | |
| import ( | |
| "golang.org/x/text/language" | |
| ) | |
| // TODO: consider if (some of the) matching algorithm needs to be public after | |
| // getting some feel about what is generic and what is specific. | |
| // NewInheritanceMatcher returns a matcher that matches based on the inheritance | |
| // chain. | |
| // | |
| // The matcher uses canonicalization and the parent relationship to find a | |
| // match. The resulting match will always be either Und or a language with the | |
| // same language and script as the requested language. It will not match | |
| // languages for which there is understood to be mutual or one-directional | |
| // intelligibility. | |
| // | |
| // A Match will indicate an Exact match if the language matches after | |
| // canonicalization and High if the matched tag is a parent. | |
| func NewInheritanceMatcher(t []language.Tag) *InheritanceMatcher { | |
| tags := &InheritanceMatcher{make(map[language.Tag]int)} | |
| for i, tag := range t { | |
| ct, err := language.All.Canonicalize(tag) | |
| if err != nil { | |
| ct = tag | |
| } | |
| tags.index[ct] = i | |
| } | |
| return tags | |
| } | |
| type InheritanceMatcher struct { | |
| index map[language.Tag]int | |
| } | |
| func (m InheritanceMatcher) Match(want ...language.Tag) (language.Tag, int, language.Confidence) { | |
| for _, t := range want { | |
| ct, err := language.All.Canonicalize(t) | |
| if err != nil { | |
| ct = t | |
| } | |
| conf := language.Exact | |
| for { | |
| if index, ok := m.index[ct]; ok { | |
| return ct, index, conf | |
| } | |
| if ct == language.Und { | |
| break | |
| } | |
| ct = ct.Parent() | |
| conf = language.High | |
| } | |
| } | |
| return language.Und, 0, language.No | |
| } |