summaryrefslogtreecommitdiff
path: root/vendor/golang.org/x/text/feature/plural/message.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/text/feature/plural/message.go')
-rw-r--r--vendor/golang.org/x/text/feature/plural/message.go244
1 files changed, 0 insertions, 244 deletions
diff --git a/vendor/golang.org/x/text/feature/plural/message.go b/vendor/golang.org/x/text/feature/plural/message.go
deleted file mode 100644
index f931f8a..0000000
--- a/vendor/golang.org/x/text/feature/plural/message.go
+++ /dev/null
@@ -1,244 +0,0 @@
-// Copyright 2017 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 plural
-
-import (
- "fmt"
- "io/ioutil"
- "reflect"
- "strconv"
-
- "golang.org/x/text/internal/catmsg"
- "golang.org/x/text/internal/number"
- "golang.org/x/text/language"
- "golang.org/x/text/message/catalog"
-)
-
-// TODO: consider deleting this interface. Maybe VisibleDigits is always
-// sufficient and practical.
-
-// Interface is used for types that can determine their own plural form.
-type Interface interface {
- // PluralForm reports the plural form for the given language of the
- // underlying value. It also returns the integer value. If the integer value
- // is larger than fits in n, PluralForm may return a value modulo
- // 10,000,000.
- PluralForm(t language.Tag, scale int) (f Form, n int)
-}
-
-// Selectf returns the first case for which its selector is a match for the
-// arg-th substitution argument to a formatting call, formatting it as indicated
-// by format.
-//
-// The cases argument are pairs of selectors and messages. Selectors are of type
-// string or Form. Messages are of type string or catalog.Message. A selector
-// matches an argument if:
-// - it is "other" or Other
-// - it matches the plural form of the argument: "zero", "one", "two", "few",
-// or "many", or the equivalent Form
-// - it is of the form "=x" where x is an integer that matches the value of
-// the argument.
-// - it is of the form "<x" where x is an integer that is larger than the
-// argument.
-//
-// The format argument determines the formatting parameters for which to
-// determine the plural form. This is especially relevant for non-integer
-// values.
-//
-// The format string may be "", in which case a best-effort attempt is made to
-// find a reasonable representation on which to base the plural form. Examples
-// of format strings are:
-// - %.2f decimal with scale 2
-// - %.2e scientific notation with precision 3 (scale + 1)
-// - %d integer
-func Selectf(arg int, format string, cases ...interface{}) catalog.Message {
- var p parser
- // Intercept the formatting parameters of format by doing a dummy print.
- fmt.Fprintf(ioutil.Discard, format, &p)
- m := &message{arg, kindDefault, 0, cases}
- switch p.verb {
- case 'g':
- m.kind = kindPrecision
- m.scale = p.scale
- case 'f':
- m.kind = kindScale
- m.scale = p.scale
- case 'e':
- m.kind = kindScientific
- m.scale = p.scale
- case 'd':
- m.kind = kindScale
- m.scale = 0
- default:
- // TODO: do we need to handle errors?
- }
- return m
-}
-
-type parser struct {
- verb rune
- scale int
-}
-
-func (p *parser) Format(s fmt.State, verb rune) {
- p.verb = verb
- p.scale = -1
- if prec, ok := s.Precision(); ok {
- p.scale = prec
- }
-}
-
-type message struct {
- arg int
- kind int
- scale int
- cases []interface{}
-}
-
-const (
- // Start with non-ASCII to allow skipping values.
- kindDefault = 0x80 + iota
- kindScale // verb f, number of fraction digits follows
- kindScientific // verb e, number of fraction digits follows
- kindPrecision // verb g, number of significant digits follows
-)
-
-var handle = catmsg.Register("golang.org/x/text/feature/plural:plural", execute)
-
-func (m *message) Compile(e *catmsg.Encoder) error {
- e.EncodeMessageType(handle)
-
- e.EncodeUint(uint64(m.arg))
-
- e.EncodeUint(uint64(m.kind))
- if m.kind > kindDefault {
- e.EncodeUint(uint64(m.scale))
- }
-
- forms := validForms(cardinal, e.Language())
-
- for i := 0; i < len(m.cases); {
- if err := compileSelector(e, forms, m.cases[i]); err != nil {
- return err
- }
- if i++; i >= len(m.cases) {
- return fmt.Errorf("plural: no message defined for selector %v", m.cases[i-1])
- }
- var msg catalog.Message
- switch x := m.cases[i].(type) {
- case string:
- msg = catalog.String(x)
- case catalog.Message:
- msg = x
- default:
- return fmt.Errorf("plural: message of type %T; must be string or catalog.Message", x)
- }
- if err := e.EncodeMessage(msg); err != nil {
- return err
- }
- i++
- }
- return nil
-}
-
-func compileSelector(e *catmsg.Encoder, valid []Form, selector interface{}) error {
- form := Other
- switch x := selector.(type) {
- case string:
- if x == "" {
- return fmt.Errorf("plural: empty selector")
- }
- if c := x[0]; c == '=' || c == '<' {
- val, err := strconv.ParseUint(x[1:], 10, 16)
- if err != nil {
- return fmt.Errorf("plural: invalid number in selector %q: %v", selector, err)
- }
- e.EncodeUint(uint64(c))
- e.EncodeUint(val)
- return nil
- }
- var ok bool
- form, ok = countMap[x]
- if !ok {
- return fmt.Errorf("plural: invalid plural form %q", selector)
- }
- case Form:
- form = x
- default:
- return fmt.Errorf("plural: selector of type %T; want string or Form", selector)
- }
-
- ok := false
- for _, f := range valid {
- if f == form {
- ok = true
- break
- }
- }
- if !ok {
- return fmt.Errorf("plural: form %q not supported for language %q", selector, e.Language())
- }
- e.EncodeUint(uint64(form))
- return nil
-}
-
-func execute(d *catmsg.Decoder) bool {
- lang := d.Language()
- argN := int(d.DecodeUint())
- kind := int(d.DecodeUint())
- scale := -1 // default
- if kind > kindDefault {
- scale = int(d.DecodeUint())
- }
- form := Other
- n := -1
- if arg := d.Arg(argN); arg == nil {
- // Default to Other.
- } else if x, ok := arg.(number.VisibleDigits); ok {
- d := x.Digits(nil, lang, scale)
- form, n = cardinal.matchDisplayDigits(lang, &d)
- } else if x, ok := arg.(Interface); ok {
- // This covers lists and formatters from the number package.
- form, n = x.PluralForm(lang, scale)
- } else {
- var f number.Formatter
- switch kind {
- case kindScale:
- f.InitDecimal(lang)
- f.SetScale(scale)
- case kindScientific:
- f.InitScientific(lang)
- f.SetScale(scale)
- case kindPrecision:
- f.InitDecimal(lang)
- f.SetPrecision(scale)
- case kindDefault:
- // sensible default
- f.InitDecimal(lang)
- if k := reflect.TypeOf(arg).Kind(); reflect.Int <= k && k <= reflect.Uintptr {
- f.SetScale(0)
- } else {
- f.SetScale(2)
- }
- }
- var dec number.Decimal // TODO: buffer in Printer
- dec.Convert(f.RoundingContext, arg)
- v := number.FormatDigits(&dec, f.RoundingContext)
- if !v.NaN && !v.Inf {
- form, n = cardinal.matchDisplayDigits(d.Language(), &v)
- }
- }
- for !d.Done() {
- f := d.DecodeUint()
- if (f == '=' && n == int(d.DecodeUint())) ||
- (f == '<' && 0 <= n && n < int(d.DecodeUint())) ||
- form == Form(f) ||
- Other == Form(f) {
- return d.ExecuteMessage()
- }
- d.SkipMessage()
- }
- return false
-}