mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-14 10:53:34 +00:00
vendor files
This commit is contained in:
67
vendor/golang.org/x/text/currency/common.go
generated
vendored
Normal file
67
vendor/golang.org/x/text/currency/common.go
generated
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||
|
||||
package currency
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
// This file contains code common to gen.go and the package code.
|
||||
|
||||
const (
|
||||
cashShift = 3
|
||||
roundMask = 0x7
|
||||
|
||||
nonTenderBit = 0x8000
|
||||
)
|
||||
|
||||
// currencyInfo contains information about a currency.
|
||||
// bits 0..2: index into roundings for standard rounding
|
||||
// bits 3..5: index into roundings for cash rounding
|
||||
type currencyInfo byte
|
||||
|
||||
// roundingType defines the scale (number of fractional decimals) and increments
|
||||
// in terms of units of size 10^-scale. For example, for scale == 2 and
|
||||
// increment == 1, the currency is rounded to units of 0.01.
|
||||
type roundingType struct {
|
||||
scale, increment uint8
|
||||
}
|
||||
|
||||
// roundings contains rounding data for currencies. This struct is
|
||||
// created by hand as it is very unlikely to change much.
|
||||
var roundings = [...]roundingType{
|
||||
{2, 1}, // default
|
||||
{0, 1},
|
||||
{1, 1},
|
||||
{3, 1},
|
||||
{4, 1},
|
||||
{2, 5}, // cash rounding alternative
|
||||
{2, 50},
|
||||
}
|
||||
|
||||
// regionToCode returns a 16-bit region code. Only two-letter codes are
|
||||
// supported. (Three-letter codes are not needed.)
|
||||
func regionToCode(r language.Region) uint16 {
|
||||
if s := r.String(); len(s) == 2 {
|
||||
return uint16(s[0])<<8 | uint16(s[1])
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func toDate(t time.Time) uint32 {
|
||||
y := t.Year()
|
||||
if y == 1 {
|
||||
return 0
|
||||
}
|
||||
date := uint32(y) << 4
|
||||
date |= uint32(t.Month())
|
||||
date <<= 5
|
||||
date |= uint32(t.Day())
|
||||
return date
|
||||
}
|
||||
|
||||
func fromDate(date uint32) time.Time {
|
||||
return time.Date(int(date>>9), time.Month((date>>5)&0xf), int(date&0x1f), 0, 0, 0, 0, time.UTC)
|
||||
}
|
185
vendor/golang.org/x/text/currency/currency.go
generated
vendored
Normal file
185
vendor/golang.org/x/text/currency/currency.go
generated
vendored
Normal file
@ -0,0 +1,185 @@
|
||||
// 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.
|
||||
|
||||
//go:generate go run gen.go gen_common.go -output tables.go
|
||||
|
||||
// Package currency contains currency-related functionality.
|
||||
//
|
||||
// NOTE: the formatting functionality is currently under development and may
|
||||
// change without notice.
|
||||
package currency // import "golang.org/x/text/currency"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sort"
|
||||
|
||||
"golang.org/x/text/internal/tag"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
// TODO:
|
||||
// - language-specific currency names.
|
||||
// - currency formatting.
|
||||
// - currency information per region
|
||||
// - register currency code (there are no private use area)
|
||||
|
||||
// TODO: remove Currency type from package language.
|
||||
|
||||
// Kind determines the rounding and rendering properties of a currency value.
|
||||
type Kind struct {
|
||||
rounding rounding
|
||||
// TODO: formatting type: standard, accounting. See CLDR.
|
||||
}
|
||||
|
||||
type rounding byte
|
||||
|
||||
const (
|
||||
standard rounding = iota
|
||||
cash
|
||||
)
|
||||
|
||||
var (
|
||||
// Standard defines standard rounding and formatting for currencies.
|
||||
Standard Kind = Kind{rounding: standard}
|
||||
|
||||
// Cash defines rounding and formatting standards for cash transactions.
|
||||
Cash Kind = Kind{rounding: cash}
|
||||
|
||||
// Accounting defines rounding and formatting standards for accounting.
|
||||
Accounting Kind = Kind{rounding: standard}
|
||||
)
|
||||
|
||||
// Rounding reports the rounding characteristics for the given currency, where
|
||||
// scale is the number of fractional decimals and increment is the number of
|
||||
// units in terms of 10^(-scale) to which to round to.
|
||||
func (k Kind) Rounding(cur Unit) (scale, increment int) {
|
||||
info := currency.Elem(int(cur.index))[3]
|
||||
switch k.rounding {
|
||||
case standard:
|
||||
info &= roundMask
|
||||
case cash:
|
||||
info >>= cashShift
|
||||
}
|
||||
return int(roundings[info].scale), int(roundings[info].increment)
|
||||
}
|
||||
|
||||
// Unit is an ISO 4217 currency designator.
|
||||
type Unit struct {
|
||||
index uint16
|
||||
}
|
||||
|
||||
// String returns the ISO code of u.
|
||||
func (u Unit) String() string {
|
||||
if u.index == 0 {
|
||||
return "XXX"
|
||||
}
|
||||
return currency.Elem(int(u.index))[:3]
|
||||
}
|
||||
|
||||
// Amount creates an Amount for the given currency unit and amount.
|
||||
func (u Unit) Amount(amount interface{}) Amount {
|
||||
// TODO: verify amount is a supported number type
|
||||
return Amount{amount: amount, currency: u}
|
||||
}
|
||||
|
||||
var (
|
||||
errSyntax = errors.New("currency: tag is not well-formed")
|
||||
errValue = errors.New("currency: tag is not a recognized currency")
|
||||
)
|
||||
|
||||
// ParseISO parses a 3-letter ISO 4217 currency code. It returns an error if s
|
||||
// is not well-formed or not a recognized currency code.
|
||||
func ParseISO(s string) (Unit, error) {
|
||||
var buf [4]byte // Take one byte more to detect oversize keys.
|
||||
key := buf[:copy(buf[:], s)]
|
||||
if !tag.FixCase("XXX", key) {
|
||||
return Unit{}, errSyntax
|
||||
}
|
||||
if i := currency.Index(key); i >= 0 {
|
||||
if i == xxx {
|
||||
return Unit{}, nil
|
||||
}
|
||||
return Unit{uint16(i)}, nil
|
||||
}
|
||||
return Unit{}, errValue
|
||||
}
|
||||
|
||||
// MustParseISO is like ParseISO, but panics if the given currency unit
|
||||
// cannot be parsed. It simplifies safe initialization of Unit values.
|
||||
func MustParseISO(s string) Unit {
|
||||
c, err := ParseISO(s)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// FromRegion reports the currency unit that is currently legal tender in the
|
||||
// given region according to CLDR. It will return false if region currently does
|
||||
// not have a legal tender.
|
||||
func FromRegion(r language.Region) (currency Unit, ok bool) {
|
||||
x := regionToCode(r)
|
||||
i := sort.Search(len(regionToCurrency), func(i int) bool {
|
||||
return regionToCurrency[i].region >= x
|
||||
})
|
||||
if i < len(regionToCurrency) && regionToCurrency[i].region == x {
|
||||
return Unit{regionToCurrency[i].code}, true
|
||||
}
|
||||
return Unit{}, false
|
||||
}
|
||||
|
||||
// FromTag reports the most likely currency for the given tag. It considers the
|
||||
// currency defined in the -u extension and infers the region if necessary.
|
||||
func FromTag(t language.Tag) (Unit, language.Confidence) {
|
||||
if cur := t.TypeForKey("cu"); len(cur) == 3 {
|
||||
c, _ := ParseISO(cur)
|
||||
return c, language.Exact
|
||||
}
|
||||
r, conf := t.Region()
|
||||
if cur, ok := FromRegion(r); ok {
|
||||
return cur, conf
|
||||
}
|
||||
return Unit{}, language.No
|
||||
}
|
||||
|
||||
var (
|
||||
// Undefined and testing.
|
||||
XXX Unit = Unit{}
|
||||
XTS Unit = Unit{xts}
|
||||
|
||||
// G10 currencies https://en.wikipedia.org/wiki/G10_currencies.
|
||||
USD Unit = Unit{usd}
|
||||
EUR Unit = Unit{eur}
|
||||
JPY Unit = Unit{jpy}
|
||||
GBP Unit = Unit{gbp}
|
||||
CHF Unit = Unit{chf}
|
||||
AUD Unit = Unit{aud}
|
||||
NZD Unit = Unit{nzd}
|
||||
CAD Unit = Unit{cad}
|
||||
SEK Unit = Unit{sek}
|
||||
NOK Unit = Unit{nok}
|
||||
|
||||
// Additional common currencies as defined by CLDR.
|
||||
BRL Unit = Unit{brl}
|
||||
CNY Unit = Unit{cny}
|
||||
DKK Unit = Unit{dkk}
|
||||
INR Unit = Unit{inr}
|
||||
RUB Unit = Unit{rub}
|
||||
HKD Unit = Unit{hkd}
|
||||
IDR Unit = Unit{idr}
|
||||
KRW Unit = Unit{krw}
|
||||
MXN Unit = Unit{mxn}
|
||||
PLN Unit = Unit{pln}
|
||||
SAR Unit = Unit{sar}
|
||||
THB Unit = Unit{thb}
|
||||
TRY Unit = Unit{try}
|
||||
TWD Unit = Unit{twd}
|
||||
ZAR Unit = Unit{zar}
|
||||
|
||||
// Precious metals.
|
||||
XAG Unit = Unit{xag}
|
||||
XAU Unit = Unit{xau}
|
||||
XPT Unit = Unit{xpt}
|
||||
XPD Unit = Unit{xpd}
|
||||
)
|
171
vendor/golang.org/x/text/currency/currency_test.go
generated
vendored
Normal file
171
vendor/golang.org/x/text/currency/currency_test.go
generated
vendored
Normal file
@ -0,0 +1,171 @@
|
||||
// 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 currency
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/text/internal/testtext"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
var (
|
||||
cup = MustParseISO("CUP")
|
||||
czk = MustParseISO("CZK")
|
||||
xcd = MustParseISO("XCD")
|
||||
zwr = MustParseISO("ZWR")
|
||||
)
|
||||
|
||||
func TestParseISO(t *testing.T) {
|
||||
testCases := []struct {
|
||||
in string
|
||||
out Unit
|
||||
ok bool
|
||||
}{
|
||||
{"USD", USD, true},
|
||||
{"xxx", XXX, true},
|
||||
{"xts", XTS, true},
|
||||
{"XX", XXX, false},
|
||||
{"XXXX", XXX, false},
|
||||
{"", XXX, false}, // not well-formed
|
||||
{"UUU", XXX, false}, // unknown
|
||||
{"\u22A9", XXX, false}, // non-ASCII, printable
|
||||
|
||||
{"aaa", XXX, false},
|
||||
{"zzz", XXX, false},
|
||||
{"000", XXX, false},
|
||||
{"999", XXX, false},
|
||||
{"---", XXX, false},
|
||||
{"\x00\x00\x00", XXX, false},
|
||||
{"\xff\xff\xff", XXX, false},
|
||||
}
|
||||
for i, tc := range testCases {
|
||||
if x, err := ParseISO(tc.in); x != tc.out || err == nil != tc.ok {
|
||||
t.Errorf("%d:%s: was %s, %v; want %s, %v", i, tc.in, x, err == nil, tc.out, tc.ok)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFromRegion(t *testing.T) {
|
||||
testCases := []struct {
|
||||
region string
|
||||
currency Unit
|
||||
ok bool
|
||||
}{
|
||||
{"NL", EUR, true},
|
||||
{"BE", EUR, true},
|
||||
{"AG", xcd, true},
|
||||
{"CH", CHF, true},
|
||||
{"CU", cup, true}, // first of multiple
|
||||
{"DG", USD, true}, // does not have M49 code
|
||||
{"150", XXX, false}, // implicit false
|
||||
{"CP", XXX, false}, // explicit false in CLDR
|
||||
{"CS", XXX, false}, // all expired
|
||||
{"ZZ", XXX, false}, // none match
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
cur, ok := FromRegion(language.MustParseRegion(tc.region))
|
||||
if cur != tc.currency || ok != tc.ok {
|
||||
t.Errorf("%s: got %v, %v; want %v, %v", tc.region, cur, ok, tc.currency, tc.ok)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFromTag(t *testing.T) {
|
||||
testCases := []struct {
|
||||
tag string
|
||||
currency Unit
|
||||
conf language.Confidence
|
||||
}{
|
||||
{"nl", EUR, language.Low}, // nl also spoken outside Euro land.
|
||||
{"nl-BE", EUR, language.Exact}, // region is known
|
||||
{"pt", BRL, language.Low},
|
||||
{"en", USD, language.Low},
|
||||
{"en-u-cu-eur", EUR, language.Exact},
|
||||
{"tlh", XXX, language.No}, // Klingon has no country.
|
||||
{"es-419", XXX, language.No},
|
||||
{"und", USD, language.Low},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
cur, conf := FromTag(language.MustParse(tc.tag))
|
||||
if cur != tc.currency || conf != tc.conf {
|
||||
t.Errorf("%s: got %v, %v; want %v, %v", tc.tag, cur, conf, tc.currency, tc.conf)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTable(t *testing.T) {
|
||||
for i := 4; i < len(currency); i += 4 {
|
||||
if a, b := currency[i-4:i-1], currency[i:i+3]; a >= b {
|
||||
t.Errorf("currency unordered at element %d: %s >= %s", i, a, b)
|
||||
}
|
||||
}
|
||||
// First currency has index 1, last is numCurrencies.
|
||||
if c := currency.Elem(1)[:3]; c != "ADP" {
|
||||
t.Errorf("first was %q; want ADP", c)
|
||||
}
|
||||
if c := currency.Elem(numCurrencies)[:3]; c != "ZWR" {
|
||||
t.Errorf("last was %q; want ZWR", c)
|
||||
}
|
||||
}
|
||||
|
||||
func TestKindRounding(t *testing.T) {
|
||||
testCases := []struct {
|
||||
kind Kind
|
||||
cur Unit
|
||||
scale int
|
||||
inc int
|
||||
}{
|
||||
{Standard, USD, 2, 1},
|
||||
{Standard, CHF, 2, 1},
|
||||
{Cash, CHF, 2, 5},
|
||||
{Standard, TWD, 2, 1},
|
||||
{Cash, TWD, 0, 1},
|
||||
{Standard, czk, 2, 1},
|
||||
{Cash, czk, 0, 1},
|
||||
{Standard, zwr, 2, 1},
|
||||
{Cash, zwr, 0, 1},
|
||||
{Standard, KRW, 0, 1},
|
||||
{Cash, KRW, 0, 1}, // Cash defaults to standard.
|
||||
}
|
||||
for i, tc := range testCases {
|
||||
if scale, inc := tc.kind.Rounding(tc.cur); scale != tc.scale && inc != tc.inc {
|
||||
t.Errorf("%d: got %d, %d; want %d, %d", i, scale, inc, tc.scale, tc.inc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const body = `package main
|
||||
import (
|
||||
"fmt"
|
||||
"golang.org/x/text/currency"
|
||||
)
|
||||
func main() {
|
||||
%s
|
||||
}
|
||||
`
|
||||
|
||||
func TestLinking(t *testing.T) {
|
||||
base := getSize(t, `fmt.Print(currency.CLDRVersion)`)
|
||||
symbols := getSize(t, `fmt.Print(currency.Symbol(currency.USD))`)
|
||||
if d := symbols - base; d < 2*1024 {
|
||||
t.Errorf("size(symbols)-size(base) was %d; want > 2K", d)
|
||||
}
|
||||
}
|
||||
|
||||
func getSize(t *testing.T, main string) int {
|
||||
size, err := testtext.CodeSize(fmt.Sprintf(body, main))
|
||||
if err != nil {
|
||||
t.Skipf("skipping link size test; binary size could not be determined: %v", err)
|
||||
}
|
||||
return size
|
||||
}
|
||||
|
||||
func BenchmarkString(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
USD.String()
|
||||
}
|
||||
}
|
27
vendor/golang.org/x/text/currency/example_test.go
generated
vendored
Normal file
27
vendor/golang.org/x/text/currency/example_test.go
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright 2016 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 currency_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"golang.org/x/text/currency"
|
||||
)
|
||||
|
||||
func ExampleQuery() {
|
||||
t1799, _ := time.Parse("2006-01-02", "1799-01-01")
|
||||
for it := currency.Query(currency.Date(t1799)); it.Next(); {
|
||||
from := ""
|
||||
if t, ok := it.From(); ok {
|
||||
from = t.Format("2006-01-02")
|
||||
}
|
||||
fmt.Printf("%v is used in %v since: %v\n", it.Unit(), it.Region(), from)
|
||||
}
|
||||
// Output:
|
||||
// GBP is used in GB since: 1694-07-27
|
||||
// GIP is used in GI since: 1713-01-01
|
||||
// USD is used in US since: 1792-01-01
|
||||
}
|
215
vendor/golang.org/x/text/currency/format.go
generated
vendored
Normal file
215
vendor/golang.org/x/text/currency/format.go
generated
vendored
Normal file
@ -0,0 +1,215 @@
|
||||
// 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 currency
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"sort"
|
||||
|
||||
"golang.org/x/text/internal"
|
||||
"golang.org/x/text/internal/format"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
// Amount is an amount-currency unit pair.
|
||||
type Amount struct {
|
||||
amount interface{} // Change to decimal(64|128).
|
||||
currency Unit
|
||||
}
|
||||
|
||||
// Currency reports the currency unit of this amount.
|
||||
func (a Amount) Currency() Unit { return a.currency }
|
||||
|
||||
// TODO: based on decimal type, but may make sense to customize a bit.
|
||||
// func (a Amount) Decimal()
|
||||
// func (a Amount) Int() (int64, error)
|
||||
// func (a Amount) Fraction() (int64, error)
|
||||
// func (a Amount) Rat() *big.Rat
|
||||
// func (a Amount) Float() (float64, error)
|
||||
// func (a Amount) Scale() uint
|
||||
// func (a Amount) Precision() uint
|
||||
// func (a Amount) Sign() int
|
||||
//
|
||||
// Add/Sub/Div/Mul/Round.
|
||||
|
||||
var space = []byte(" ")
|
||||
|
||||
// Format implements fmt.Formatter. It accepts format.State for
|
||||
// language-specific rendering.
|
||||
func (a Amount) Format(s fmt.State, verb rune) {
|
||||
v := formattedValue{
|
||||
currency: a.currency,
|
||||
amount: a.amount,
|
||||
format: defaultFormat,
|
||||
}
|
||||
v.Format(s, verb)
|
||||
}
|
||||
|
||||
// formattedValue is currency amount or unit that implements language-sensitive
|
||||
// formatting.
|
||||
type formattedValue struct {
|
||||
currency Unit
|
||||
amount interface{} // Amount, Unit, or number.
|
||||
format *options
|
||||
}
|
||||
|
||||
// Format implements fmt.Formatter. It accepts format.State for
|
||||
// language-specific rendering.
|
||||
func (v formattedValue) Format(s fmt.State, verb rune) {
|
||||
var lang int
|
||||
if state, ok := s.(format.State); ok {
|
||||
lang, _ = language.CompactIndex(state.Language())
|
||||
}
|
||||
|
||||
// Get the options. Use DefaultFormat if not present.
|
||||
opt := v.format
|
||||
if opt == nil {
|
||||
opt = defaultFormat
|
||||
}
|
||||
cur := v.currency
|
||||
if cur.index == 0 {
|
||||
cur = opt.currency
|
||||
}
|
||||
|
||||
// TODO: use pattern.
|
||||
io.WriteString(s, opt.symbol(lang, cur))
|
||||
if v.amount != nil {
|
||||
s.Write(space)
|
||||
|
||||
// TODO: apply currency-specific rounding
|
||||
scale, _ := opt.kind.Rounding(cur)
|
||||
if _, ok := s.Precision(); !ok {
|
||||
fmt.Fprintf(s, "%.*f", scale, v.amount)
|
||||
} else {
|
||||
fmt.Fprint(s, v.amount)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Formatter decorates a given number, Unit or Amount with formatting options.
|
||||
type Formatter func(amount interface{}) formattedValue
|
||||
|
||||
// func (f Formatter) Options(opts ...Option) Formatter
|
||||
|
||||
// TODO: call this a Formatter or FormatFunc?
|
||||
|
||||
var dummy = USD.Amount(0)
|
||||
|
||||
// adjust creates a new Formatter based on the adjustments of fn on f.
|
||||
func (f Formatter) adjust(fn func(*options)) Formatter {
|
||||
var o options = *(f(dummy).format)
|
||||
fn(&o)
|
||||
return o.format
|
||||
}
|
||||
|
||||
// Default creates a new Formatter that defaults to currency unit c if a numeric
|
||||
// value is passed that is not associated with a currency.
|
||||
func (f Formatter) Default(currency Unit) Formatter {
|
||||
return f.adjust(func(o *options) { o.currency = currency })
|
||||
}
|
||||
|
||||
// Kind sets the kind of the underlying currency unit.
|
||||
func (f Formatter) Kind(k Kind) Formatter {
|
||||
return f.adjust(func(o *options) { o.kind = k })
|
||||
}
|
||||
|
||||
var defaultFormat *options = ISO(dummy).format
|
||||
|
||||
var (
|
||||
// Uses Narrow symbols. Overrides Symbol, if present.
|
||||
NarrowSymbol Formatter = Formatter(formNarrow)
|
||||
|
||||
// Use Symbols instead of ISO codes, when available.
|
||||
Symbol Formatter = Formatter(formSymbol)
|
||||
|
||||
// Use ISO code as symbol.
|
||||
ISO Formatter = Formatter(formISO)
|
||||
|
||||
// TODO:
|
||||
// // Use full name as symbol.
|
||||
// Name Formatter
|
||||
)
|
||||
|
||||
// options configures rendering and rounding options for an Amount.
|
||||
type options struct {
|
||||
currency Unit
|
||||
kind Kind
|
||||
|
||||
symbol func(compactIndex int, c Unit) string
|
||||
}
|
||||
|
||||
func (o *options) format(amount interface{}) formattedValue {
|
||||
v := formattedValue{format: o}
|
||||
switch x := amount.(type) {
|
||||
case Amount:
|
||||
v.amount = x.amount
|
||||
v.currency = x.currency
|
||||
case *Amount:
|
||||
v.amount = x.amount
|
||||
v.currency = x.currency
|
||||
case Unit:
|
||||
v.currency = x
|
||||
case *Unit:
|
||||
v.currency = *x
|
||||
default:
|
||||
if o.currency.index == 0 {
|
||||
panic("cannot format number without a currency being set")
|
||||
}
|
||||
// TODO: Must be a number.
|
||||
v.amount = x
|
||||
v.currency = o.currency
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
var (
|
||||
optISO = options{symbol: lookupISO}
|
||||
optSymbol = options{symbol: lookupSymbol}
|
||||
optNarrow = options{symbol: lookupNarrow}
|
||||
)
|
||||
|
||||
// These need to be functions, rather than curried methods, as curried methods
|
||||
// are evaluated at init time, causing tables to be included unconditionally.
|
||||
func formISO(x interface{}) formattedValue { return optISO.format(x) }
|
||||
func formSymbol(x interface{}) formattedValue { return optSymbol.format(x) }
|
||||
func formNarrow(x interface{}) formattedValue { return optNarrow.format(x) }
|
||||
|
||||
func lookupISO(x int, c Unit) string { return c.String() }
|
||||
func lookupSymbol(x int, c Unit) string { return normalSymbol.lookup(x, c) }
|
||||
func lookupNarrow(x int, c Unit) string { return narrowSymbol.lookup(x, c) }
|
||||
|
||||
type symbolIndex struct {
|
||||
index []uint16 // position corresponds with compact index of language.
|
||||
data []curToIndex
|
||||
}
|
||||
|
||||
var (
|
||||
normalSymbol = symbolIndex{normalLangIndex, normalSymIndex}
|
||||
narrowSymbol = symbolIndex{narrowLangIndex, narrowSymIndex}
|
||||
)
|
||||
|
||||
func (x *symbolIndex) lookup(lang int, c Unit) string {
|
||||
for {
|
||||
index := x.data[x.index[lang]:x.index[lang+1]]
|
||||
i := sort.Search(len(index), func(i int) bool {
|
||||
return index[i].cur >= c.index
|
||||
})
|
||||
if i < len(index) && index[i].cur == c.index {
|
||||
x := index[i].idx
|
||||
start := x + 1
|
||||
end := start + uint16(symbols[x])
|
||||
if start == end {
|
||||
return c.String()
|
||||
}
|
||||
return symbols[start:end]
|
||||
}
|
||||
if lang == 0 {
|
||||
break
|
||||
}
|
||||
lang = int(internal.Parent[lang])
|
||||
}
|
||||
return c.String()
|
||||
}
|
70
vendor/golang.org/x/text/currency/format_test.go
generated
vendored
Normal file
70
vendor/golang.org/x/text/currency/format_test.go
generated
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
// 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 currency
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"golang.org/x/text/language"
|
||||
"golang.org/x/text/message"
|
||||
)
|
||||
|
||||
var (
|
||||
en = language.English
|
||||
fr = language.French
|
||||
en_US = language.AmericanEnglish
|
||||
en_GB = language.BritishEnglish
|
||||
en_AU = language.MustParse("en-AU")
|
||||
und = language.Und
|
||||
)
|
||||
|
||||
func TestFormatting(t *testing.T) {
|
||||
testCases := []struct {
|
||||
tag language.Tag
|
||||
value interface{}
|
||||
format Formatter
|
||||
want string
|
||||
}{
|
||||
0: {en, USD.Amount(0.1), nil, "USD 0.10"},
|
||||
1: {en, XPT.Amount(1.0), Symbol, "XPT 1.00"},
|
||||
|
||||
2: {en, USD.Amount(2.0), ISO, "USD 2.00"},
|
||||
3: {und, USD.Amount(3.0), Symbol, "US$ 3.00"},
|
||||
4: {en, USD.Amount(4.0), Symbol, "$ 4.00"},
|
||||
|
||||
5: {en, USD.Amount(5.20), NarrowSymbol, "$ 5.20"},
|
||||
6: {en, AUD.Amount(6.20), Symbol, "A$ 6.20"},
|
||||
|
||||
7: {en_AU, AUD.Amount(7.20), Symbol, "$ 7.20"},
|
||||
8: {en_GB, USD.Amount(8.20), Symbol, "US$ 8.20"},
|
||||
|
||||
9: {en, 9.0, Symbol.Default(EUR), "€ 9.00"},
|
||||
10: {en, 10.123, Symbol.Default(KRW), "₩ 10"},
|
||||
11: {fr, 11.52, Symbol.Default(TWD), "TWD 11.52"},
|
||||
12: {en, 12.123, Symbol.Default(czk), "CZK 12.12"},
|
||||
13: {en, 13.123, Symbol.Default(czk).Kind(Cash), "CZK 13"},
|
||||
14: {en, 14.12345, ISO.Default(MustParseISO("CLF")), "CLF 14.1235"},
|
||||
15: {en, USD.Amount(15.00), ISO.Default(TWD), "USD 15.00"},
|
||||
16: {en, KRW.Amount(16.00), ISO.Kind(Cash), "KRW 16"},
|
||||
|
||||
// TODO: support integers as well.
|
||||
|
||||
17: {en, USD, nil, "USD"},
|
||||
18: {en, USD, ISO, "USD"},
|
||||
19: {en, USD, Symbol, "$"},
|
||||
20: {en_GB, USD, Symbol, "US$"},
|
||||
21: {en_AU, USD, NarrowSymbol, "$"},
|
||||
}
|
||||
for i, tc := range testCases {
|
||||
p := message.NewPrinter(tc.tag)
|
||||
v := tc.value
|
||||
if tc.format != nil {
|
||||
v = tc.format(v)
|
||||
}
|
||||
if got := p.Sprint(v); got != tc.want {
|
||||
t.Errorf("%d: got %q; want %q", i, got, tc.want)
|
||||
}
|
||||
}
|
||||
}
|
400
vendor/golang.org/x/text/currency/gen.go
generated
vendored
Normal file
400
vendor/golang.org/x/text/currency/gen.go
generated
vendored
Normal file
@ -0,0 +1,400 @@
|
||||
// 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.
|
||||
|
||||
// +build ignore
|
||||
|
||||
// Generator for currency-related data.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"golang.org/x/text/internal"
|
||||
"golang.org/x/text/internal/gen"
|
||||
"golang.org/x/text/internal/tag"
|
||||
"golang.org/x/text/language"
|
||||
"golang.org/x/text/unicode/cldr"
|
||||
)
|
||||
|
||||
var (
|
||||
test = flag.Bool("test", false,
|
||||
"test existing tables; can be used to compare web data with package data.")
|
||||
outputFile = flag.String("output", "tables.go", "output file")
|
||||
|
||||
draft = flag.String("draft",
|
||||
"contributed",
|
||||
`Minimal draft requirements (approved, contributed, provisional, unconfirmed).`)
|
||||
)
|
||||
|
||||
func main() {
|
||||
gen.Init()
|
||||
|
||||
gen.Repackage("gen_common.go", "common.go", "currency")
|
||||
|
||||
// Read the CLDR zip file.
|
||||
r := gen.OpenCLDRCoreZip()
|
||||
defer r.Close()
|
||||
|
||||
d := &cldr.Decoder{}
|
||||
d.SetDirFilter("supplemental", "main")
|
||||
d.SetSectionFilter("numbers")
|
||||
data, err := d.DecodeZip(r)
|
||||
if err != nil {
|
||||
log.Fatalf("DecodeZip: %v", err)
|
||||
}
|
||||
|
||||
w := gen.NewCodeWriter()
|
||||
defer w.WriteGoFile(*outputFile, "currency")
|
||||
|
||||
fmt.Fprintln(w, `import "golang.org/x/text/internal/tag"`)
|
||||
|
||||
gen.WriteCLDRVersion(w)
|
||||
b := &builder{}
|
||||
b.genCurrencies(w, data.Supplemental())
|
||||
b.genSymbols(w, data)
|
||||
}
|
||||
|
||||
var constants = []string{
|
||||
// Undefined and testing.
|
||||
"XXX", "XTS",
|
||||
// G11 currencies https://en.wikipedia.org/wiki/G10_currencies.
|
||||
"USD", "EUR", "JPY", "GBP", "CHF", "AUD", "NZD", "CAD", "SEK", "NOK", "DKK",
|
||||
// Precious metals.
|
||||
"XAG", "XAU", "XPT", "XPD",
|
||||
|
||||
// Additional common currencies as defined by CLDR.
|
||||
"BRL", "CNY", "INR", "RUB", "HKD", "IDR", "KRW", "MXN", "PLN", "SAR",
|
||||
"THB", "TRY", "TWD", "ZAR",
|
||||
}
|
||||
|
||||
type builder struct {
|
||||
currencies tag.Index
|
||||
numCurrencies int
|
||||
}
|
||||
|
||||
func (b *builder) genCurrencies(w *gen.CodeWriter, data *cldr.SupplementalData) {
|
||||
// 3-letter ISO currency codes
|
||||
// Start with dummy to let index start at 1.
|
||||
currencies := []string{"\x00\x00\x00\x00"}
|
||||
|
||||
// currency codes
|
||||
for _, reg := range data.CurrencyData.Region {
|
||||
for _, cur := range reg.Currency {
|
||||
currencies = append(currencies, cur.Iso4217)
|
||||
}
|
||||
}
|
||||
// Not included in the list for some reasons:
|
||||
currencies = append(currencies, "MVP")
|
||||
|
||||
sort.Strings(currencies)
|
||||
// Unique the elements.
|
||||
k := 0
|
||||
for i := 1; i < len(currencies); i++ {
|
||||
if currencies[k] != currencies[i] {
|
||||
currencies[k+1] = currencies[i]
|
||||
k++
|
||||
}
|
||||
}
|
||||
currencies = currencies[:k+1]
|
||||
|
||||
// Close with dummy for simpler and faster searching.
|
||||
currencies = append(currencies, "\xff\xff\xff\xff")
|
||||
|
||||
// Write currency values.
|
||||
fmt.Fprintln(w, "const (")
|
||||
for _, c := range constants {
|
||||
index := sort.SearchStrings(currencies, c)
|
||||
fmt.Fprintf(w, "\t%s = %d\n", strings.ToLower(c), index)
|
||||
}
|
||||
fmt.Fprint(w, ")")
|
||||
|
||||
// Compute currency-related data that we merge into the table.
|
||||
for _, info := range data.CurrencyData.Fractions[0].Info {
|
||||
if info.Iso4217 == "DEFAULT" {
|
||||
continue
|
||||
}
|
||||
standard := getRoundingIndex(info.Digits, info.Rounding, 0)
|
||||
cash := getRoundingIndex(info.CashDigits, info.CashRounding, standard)
|
||||
|
||||
index := sort.SearchStrings(currencies, info.Iso4217)
|
||||
currencies[index] += mkCurrencyInfo(standard, cash)
|
||||
}
|
||||
|
||||
// Set default values for entries that weren't touched.
|
||||
for i, c := range currencies {
|
||||
if len(c) == 3 {
|
||||
currencies[i] += mkCurrencyInfo(0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
b.currencies = tag.Index(strings.Join(currencies, ""))
|
||||
w.WriteComment(`
|
||||
currency holds an alphabetically sorted list of canonical 3-letter currency
|
||||
identifiers. Each identifier is followed by a byte of type currencyInfo,
|
||||
defined in gen_common.go.`)
|
||||
w.WriteConst("currency", b.currencies)
|
||||
|
||||
// Hack alert: gofmt indents a trailing comment after an indented string.
|
||||
// Ensure that the next thing written is not a comment.
|
||||
b.numCurrencies = (len(b.currencies) / 4) - 2
|
||||
w.WriteConst("numCurrencies", b.numCurrencies)
|
||||
|
||||
// Create a table that maps regions to currencies.
|
||||
regionToCurrency := []toCurrency{}
|
||||
|
||||
for _, reg := range data.CurrencyData.Region {
|
||||
if len(reg.Iso3166) != 2 {
|
||||
log.Fatalf("Unexpected group %q in region data", reg.Iso3166)
|
||||
}
|
||||
if len(reg.Currency) == 0 {
|
||||
continue
|
||||
}
|
||||
cur := reg.Currency[0]
|
||||
if cur.To != "" || cur.Tender == "false" {
|
||||
continue
|
||||
}
|
||||
regionToCurrency = append(regionToCurrency, toCurrency{
|
||||
region: regionToCode(language.MustParseRegion(reg.Iso3166)),
|
||||
code: uint16(b.currencies.Index([]byte(cur.Iso4217))),
|
||||
})
|
||||
}
|
||||
sort.Sort(byRegion(regionToCurrency))
|
||||
|
||||
w.WriteType(toCurrency{})
|
||||
w.WriteVar("regionToCurrency", regionToCurrency)
|
||||
|
||||
// Create a table that maps regions to currencies.
|
||||
regionData := []regionInfo{}
|
||||
|
||||
for _, reg := range data.CurrencyData.Region {
|
||||
if len(reg.Iso3166) != 2 {
|
||||
log.Fatalf("Unexpected group %q in region data", reg.Iso3166)
|
||||
}
|
||||
for _, cur := range reg.Currency {
|
||||
from, _ := time.Parse("2006-01-02", cur.From)
|
||||
to, _ := time.Parse("2006-01-02", cur.To)
|
||||
code := uint16(b.currencies.Index([]byte(cur.Iso4217)))
|
||||
if cur.Tender == "false" {
|
||||
code |= nonTenderBit
|
||||
}
|
||||
regionData = append(regionData, regionInfo{
|
||||
region: regionToCode(language.MustParseRegion(reg.Iso3166)),
|
||||
code: code,
|
||||
from: toDate(from),
|
||||
to: toDate(to),
|
||||
})
|
||||
}
|
||||
}
|
||||
sort.Stable(byRegionCode(regionData))
|
||||
|
||||
w.WriteType(regionInfo{})
|
||||
w.WriteVar("regionData", regionData)
|
||||
}
|
||||
|
||||
type regionInfo struct {
|
||||
region uint16
|
||||
code uint16 // 0x8000 not legal tender
|
||||
from uint32
|
||||
to uint32
|
||||
}
|
||||
|
||||
type byRegionCode []regionInfo
|
||||
|
||||
func (a byRegionCode) Len() int { return len(a) }
|
||||
func (a byRegionCode) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
func (a byRegionCode) Less(i, j int) bool { return a[i].region < a[j].region }
|
||||
|
||||
type toCurrency struct {
|
||||
region uint16
|
||||
code uint16
|
||||
}
|
||||
|
||||
type byRegion []toCurrency
|
||||
|
||||
func (a byRegion) Len() int { return len(a) }
|
||||
func (a byRegion) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
func (a byRegion) Less(i, j int) bool { return a[i].region < a[j].region }
|
||||
|
||||
func mkCurrencyInfo(standard, cash int) string {
|
||||
return string([]byte{byte(cash<<cashShift | standard)})
|
||||
}
|
||||
|
||||
func getRoundingIndex(digits, rounding string, defIndex int) int {
|
||||
round := roundings[defIndex] // default
|
||||
|
||||
if digits != "" {
|
||||
round.scale = parseUint8(digits)
|
||||
}
|
||||
if rounding != "" && rounding != "0" { // 0 means 1 here in CLDR
|
||||
round.increment = parseUint8(rounding)
|
||||
}
|
||||
|
||||
// Will panic if the entry doesn't exist:
|
||||
for i, r := range roundings {
|
||||
if r == round {
|
||||
return i
|
||||
}
|
||||
}
|
||||
log.Fatalf("Rounding entry %#v does not exist.", round)
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
// genSymbols generates the symbols used for currencies. Most symbols are
|
||||
// defined in root and there is only very small variation per language.
|
||||
// The following rules apply:
|
||||
// - A symbol can be requested as normal or narrow.
|
||||
// - If a symbol is not defined for a currency, it defaults to its ISO code.
|
||||
func (b *builder) genSymbols(w *gen.CodeWriter, data *cldr.CLDR) {
|
||||
d, err := cldr.ParseDraft(*draft)
|
||||
if err != nil {
|
||||
log.Fatalf("filter: %v", err)
|
||||
}
|
||||
|
||||
const (
|
||||
normal = iota
|
||||
narrow
|
||||
numTypes
|
||||
)
|
||||
// language -> currency -> type -> symbol
|
||||
var symbols [language.NumCompactTags][][numTypes]*string
|
||||
|
||||
// Collect symbol information per language.
|
||||
for _, lang := range data.Locales() {
|
||||
ldml := data.RawLDML(lang)
|
||||
if ldml.Numbers == nil || ldml.Numbers.Currencies == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
langIndex, ok := language.CompactIndex(language.MustParse(lang))
|
||||
if !ok {
|
||||
log.Fatalf("No compact index for language %s", lang)
|
||||
}
|
||||
|
||||
symbols[langIndex] = make([][numTypes]*string, b.numCurrencies+1)
|
||||
|
||||
for _, c := range ldml.Numbers.Currencies.Currency {
|
||||
syms := cldr.MakeSlice(&c.Symbol)
|
||||
syms.SelectDraft(d)
|
||||
|
||||
for _, sym := range c.Symbol {
|
||||
v := sym.Data()
|
||||
if v == c.Type {
|
||||
// We define "" to mean the ISO symbol.
|
||||
v = ""
|
||||
}
|
||||
cur := b.currencies.Index([]byte(c.Type))
|
||||
// XXX gets reassigned to 0 in the package's code.
|
||||
if c.Type == "XXX" {
|
||||
cur = 0
|
||||
}
|
||||
if cur == -1 {
|
||||
fmt.Println("Unsupported:", c.Type)
|
||||
continue
|
||||
}
|
||||
|
||||
switch sym.Alt {
|
||||
case "":
|
||||
symbols[langIndex][cur][normal] = &v
|
||||
case "narrow":
|
||||
symbols[langIndex][cur][narrow] = &v
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove values identical to the parent.
|
||||
for langIndex, data := range symbols {
|
||||
for curIndex, curs := range data {
|
||||
for typ, sym := range curs {
|
||||
if sym == nil {
|
||||
continue
|
||||
}
|
||||
for p := uint16(langIndex); p != 0; {
|
||||
p = internal.Parent[p]
|
||||
x := symbols[p]
|
||||
if x == nil {
|
||||
continue
|
||||
}
|
||||
if v := x[curIndex][typ]; v != nil || p == 0 {
|
||||
// Value is equal to the default value root value is undefined.
|
||||
parentSym := ""
|
||||
if v != nil {
|
||||
parentSym = *v
|
||||
}
|
||||
if parentSym == *sym {
|
||||
// Value is the same as parent.
|
||||
data[curIndex][typ] = nil
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create symbol index.
|
||||
symbolData := []byte{0}
|
||||
symbolLookup := map[string]uint16{"": 0} // 0 means default, so block that value.
|
||||
for _, data := range symbols {
|
||||
for _, curs := range data {
|
||||
for _, sym := range curs {
|
||||
if sym == nil {
|
||||
continue
|
||||
}
|
||||
if _, ok := symbolLookup[*sym]; !ok {
|
||||
symbolLookup[*sym] = uint16(len(symbolData))
|
||||
symbolData = append(symbolData, byte(len(*sym)))
|
||||
symbolData = append(symbolData, *sym...)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
w.WriteComment(`
|
||||
symbols holds symbol data of the form <n> <str>, where n is the length of
|
||||
the symbol string str.`)
|
||||
w.WriteConst("symbols", string(symbolData))
|
||||
|
||||
// Create index from language to currency lookup to symbol.
|
||||
type curToIndex struct{ cur, idx uint16 }
|
||||
w.WriteType(curToIndex{})
|
||||
|
||||
prefix := []string{"normal", "narrow"}
|
||||
// Create data for regular and narrow symbol data.
|
||||
for typ := normal; typ <= narrow; typ++ {
|
||||
|
||||
indexes := []curToIndex{} // maps currency to symbol index
|
||||
languages := []uint16{}
|
||||
|
||||
for _, data := range symbols {
|
||||
languages = append(languages, uint16(len(indexes)))
|
||||
for curIndex, curs := range data {
|
||||
|
||||
if sym := curs[typ]; sym != nil {
|
||||
indexes = append(indexes, curToIndex{uint16(curIndex), symbolLookup[*sym]})
|
||||
}
|
||||
}
|
||||
}
|
||||
languages = append(languages, uint16(len(indexes)))
|
||||
|
||||
w.WriteVar(prefix[typ]+"LangIndex", languages)
|
||||
w.WriteVar(prefix[typ]+"SymIndex", indexes)
|
||||
}
|
||||
}
|
||||
func parseUint8(str string) uint8 {
|
||||
x, err := strconv.ParseUint(str, 10, 8)
|
||||
if err != nil {
|
||||
// Show line number of where this function was called.
|
||||
log.New(os.Stderr, "", log.Lshortfile).Output(2, err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
return uint8(x)
|
||||
}
|
71
vendor/golang.org/x/text/currency/gen_common.go
generated
vendored
Normal file
71
vendor/golang.org/x/text/currency/gen_common.go
generated
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
// 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.
|
||||
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
// This file contains code common to gen.go and the package code.
|
||||
|
||||
const (
|
||||
cashShift = 3
|
||||
roundMask = 0x7
|
||||
|
||||
nonTenderBit = 0x8000
|
||||
)
|
||||
|
||||
// currencyInfo contains information about a currency.
|
||||
// bits 0..2: index into roundings for standard rounding
|
||||
// bits 3..5: index into roundings for cash rounding
|
||||
type currencyInfo byte
|
||||
|
||||
// roundingType defines the scale (number of fractional decimals) and increments
|
||||
// in terms of units of size 10^-scale. For example, for scale == 2 and
|
||||
// increment == 1, the currency is rounded to units of 0.01.
|
||||
type roundingType struct {
|
||||
scale, increment uint8
|
||||
}
|
||||
|
||||
// roundings contains rounding data for currencies. This struct is
|
||||
// created by hand as it is very unlikely to change much.
|
||||
var roundings = [...]roundingType{
|
||||
{2, 1}, // default
|
||||
{0, 1},
|
||||
{1, 1},
|
||||
{3, 1},
|
||||
{4, 1},
|
||||
{2, 5}, // cash rounding alternative
|
||||
{2, 50},
|
||||
}
|
||||
|
||||
// regionToCode returns a 16-bit region code. Only two-letter codes are
|
||||
// supported. (Three-letter codes are not needed.)
|
||||
func regionToCode(r language.Region) uint16 {
|
||||
if s := r.String(); len(s) == 2 {
|
||||
return uint16(s[0])<<8 | uint16(s[1])
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func toDate(t time.Time) uint32 {
|
||||
y := t.Year()
|
||||
if y == 1 {
|
||||
return 0
|
||||
}
|
||||
date := uint32(y) << 4
|
||||
date |= uint32(t.Month())
|
||||
date <<= 5
|
||||
date |= uint32(t.Day())
|
||||
return date
|
||||
}
|
||||
|
||||
func fromDate(date uint32) time.Time {
|
||||
return time.Date(int(date>>9), time.Month((date>>5)&0xf), int(date&0x1f), 0, 0, 0, 0, time.UTC)
|
||||
}
|
152
vendor/golang.org/x/text/currency/query.go
generated
vendored
Normal file
152
vendor/golang.org/x/text/currency/query.go
generated
vendored
Normal file
@ -0,0 +1,152 @@
|
||||
// Copyright 2016 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 currency
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
// QueryIter represents a set of Units. The default set includes all Units that
|
||||
// are currently in use as legal tender in any Region.
|
||||
type QueryIter interface {
|
||||
// Next returns true if there is a next element available.
|
||||
// It must be called before any of the other methods are called.
|
||||
Next() bool
|
||||
|
||||
// Unit returns the unit of the current iteration.
|
||||
Unit() Unit
|
||||
|
||||
// Region returns the Region for the current iteration.
|
||||
Region() language.Region
|
||||
|
||||
// From returns the date from which the unit was used in the region.
|
||||
// It returns false if this date is unknown.
|
||||
From() (time.Time, bool)
|
||||
|
||||
// To returns the date up till which the unit was used in the region.
|
||||
// It returns false if this date is unknown or if the unit is still in use.
|
||||
To() (time.Time, bool)
|
||||
|
||||
// IsTender reports whether the unit is a legal tender in the region during
|
||||
// the specified date range.
|
||||
IsTender() bool
|
||||
}
|
||||
|
||||
// Query represents a set of Units. The default set includes all Units that are
|
||||
// currently in use as legal tender in any Region.
|
||||
func Query(options ...QueryOption) QueryIter {
|
||||
it := &iter{
|
||||
end: len(regionData),
|
||||
date: 0xFFFFFFFF,
|
||||
}
|
||||
for _, fn := range options {
|
||||
fn(it)
|
||||
}
|
||||
return it
|
||||
}
|
||||
|
||||
// NonTender returns a new query that also includes matching Units that are not
|
||||
// legal tender.
|
||||
var NonTender QueryOption = nonTender
|
||||
|
||||
func nonTender(i *iter) {
|
||||
i.nonTender = true
|
||||
}
|
||||
|
||||
// Historical selects the units for all dates.
|
||||
var Historical QueryOption = historical
|
||||
|
||||
func historical(i *iter) {
|
||||
i.date = hist
|
||||
}
|
||||
|
||||
// A QueryOption can be used to change the set of unit information returned by
|
||||
// a query.
|
||||
type QueryOption func(*iter)
|
||||
|
||||
// Date queries the units that were in use at the given point in history.
|
||||
func Date(t time.Time) QueryOption {
|
||||
d := toDate(t)
|
||||
return func(i *iter) {
|
||||
i.date = d
|
||||
}
|
||||
}
|
||||
|
||||
// Region limits the query to only return entries for the given region.
|
||||
func Region(r language.Region) QueryOption {
|
||||
p, end := len(regionData), len(regionData)
|
||||
x := regionToCode(r)
|
||||
i := sort.Search(len(regionData), func(i int) bool {
|
||||
return regionData[i].region >= x
|
||||
})
|
||||
if i < len(regionData) && regionData[i].region == x {
|
||||
p = i
|
||||
for i++; i < len(regionData) && regionData[i].region == x; i++ {
|
||||
}
|
||||
end = i
|
||||
}
|
||||
return func(i *iter) {
|
||||
i.p, i.end = p, end
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
hist = 0x00
|
||||
now = 0xFFFFFFFF
|
||||
)
|
||||
|
||||
type iter struct {
|
||||
*regionInfo
|
||||
p, end int
|
||||
date uint32
|
||||
nonTender bool
|
||||
}
|
||||
|
||||
func (i *iter) Next() bool {
|
||||
for ; i.p < i.end; i.p++ {
|
||||
i.regionInfo = ®ionData[i.p]
|
||||
if !i.nonTender && !i.IsTender() {
|
||||
continue
|
||||
}
|
||||
if i.date == hist || (i.from <= i.date && (i.to == 0 || i.date <= i.to)) {
|
||||
i.p++
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (r *regionInfo) Region() language.Region {
|
||||
// TODO: this could be much faster.
|
||||
var buf [2]byte
|
||||
buf[0] = uint8(r.region >> 8)
|
||||
buf[1] = uint8(r.region)
|
||||
return language.MustParseRegion(string(buf[:]))
|
||||
}
|
||||
|
||||
func (r *regionInfo) Unit() Unit {
|
||||
return Unit{r.code &^ nonTenderBit}
|
||||
}
|
||||
|
||||
func (r *regionInfo) IsTender() bool {
|
||||
return r.code&nonTenderBit == 0
|
||||
}
|
||||
|
||||
func (r *regionInfo) From() (time.Time, bool) {
|
||||
if r.from == 0 {
|
||||
return time.Time{}, false
|
||||
}
|
||||
return fromDate(r.from), true
|
||||
}
|
||||
|
||||
func (r *regionInfo) To() (time.Time, bool) {
|
||||
if r.to == 0 {
|
||||
return time.Time{}, false
|
||||
}
|
||||
return fromDate(r.to), true
|
||||
}
|
107
vendor/golang.org/x/text/currency/query_test.go
generated
vendored
Normal file
107
vendor/golang.org/x/text/currency/query_test.go
generated
vendored
Normal file
@ -0,0 +1,107 @@
|
||||
// Copyright 2016 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 currency
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
func TestQuery(t *testing.T) {
|
||||
r := func(region string) language.Region {
|
||||
return language.MustParseRegion(region)
|
||||
}
|
||||
t1800, _ := time.Parse("2006-01-02", "1800-01-01")
|
||||
type result struct {
|
||||
region language.Region
|
||||
unit Unit
|
||||
isTender bool
|
||||
from, to string
|
||||
}
|
||||
testCases := []struct {
|
||||
name string
|
||||
opts []QueryOption
|
||||
results []result
|
||||
}{{
|
||||
name: "XA",
|
||||
opts: []QueryOption{Region(r("XA"))},
|
||||
results: []result{},
|
||||
}, {
|
||||
name: "AC",
|
||||
opts: []QueryOption{Region(r("AC"))},
|
||||
results: []result{
|
||||
{r("AC"), MustParseISO("SHP"), true, "1976-01-01", ""},
|
||||
},
|
||||
}, {
|
||||
name: "US",
|
||||
opts: []QueryOption{Region(r("US"))},
|
||||
results: []result{
|
||||
{r("US"), MustParseISO("USD"), true, "1792-01-01", ""},
|
||||
},
|
||||
}, {
|
||||
name: "US-hist",
|
||||
opts: []QueryOption{Region(r("US")), Historical},
|
||||
results: []result{
|
||||
{r("US"), MustParseISO("USD"), true, "1792-01-01", ""},
|
||||
},
|
||||
}, {
|
||||
name: "US-non-tender",
|
||||
opts: []QueryOption{Region(r("US")), NonTender},
|
||||
results: []result{
|
||||
{r("US"), MustParseISO("USD"), true, "1792-01-01", ""},
|
||||
{r("US"), MustParseISO("USN"), false, "", ""},
|
||||
},
|
||||
}, {
|
||||
name: "US-historical+non-tender",
|
||||
opts: []QueryOption{Region(r("US")), Historical, NonTender},
|
||||
results: []result{
|
||||
{r("US"), MustParseISO("USD"), true, "1792-01-01", ""},
|
||||
{r("US"), MustParseISO("USN"), false, "", ""},
|
||||
{r("US"), MustParseISO("USS"), false, "", "2014-03-01"},
|
||||
},
|
||||
}, {
|
||||
name: "1800",
|
||||
opts: []QueryOption{Date(t1800)},
|
||||
results: []result{
|
||||
{r("CH"), MustParseISO("CHF"), true, "1799-03-17", ""},
|
||||
{r("GB"), MustParseISO("GBP"), true, "1694-07-27", ""},
|
||||
{r("GI"), MustParseISO("GIP"), true, "1713-01-01", ""},
|
||||
// The date for IE and PR seem wrong, so these may be updated at
|
||||
// some point causing the tests to fail.
|
||||
{r("IE"), MustParseISO("GBP"), true, "1800-01-01", "1922-01-01"},
|
||||
{r("PR"), MustParseISO("ESP"), true, "1800-01-01", "1898-12-10"},
|
||||
{r("US"), MustParseISO("USD"), true, "1792-01-01", ""},
|
||||
},
|
||||
}}
|
||||
for _, tc := range testCases {
|
||||
n := 0
|
||||
for it := Query(tc.opts...); it.Next(); n++ {
|
||||
if n < len(tc.results) {
|
||||
got := result{
|
||||
it.Region(),
|
||||
it.Unit(),
|
||||
it.IsTender(),
|
||||
getTime(it.From()),
|
||||
getTime(it.To()),
|
||||
}
|
||||
if got != tc.results[n] {
|
||||
t.Errorf("%s:%d: got %v; want %v", tc.name, n, got, tc.results[n])
|
||||
}
|
||||
}
|
||||
}
|
||||
if n != len(tc.results) {
|
||||
t.Errorf("%s: unexpected number of results: got %d; want %d", tc.name, n, len(tc.results))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getTime(t time.Time, ok bool) string {
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
return t.Format("2006-01-02")
|
||||
}
|
2629
vendor/golang.org/x/text/currency/tables.go
generated
vendored
Normal file
2629
vendor/golang.org/x/text/currency/tables.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
93
vendor/golang.org/x/text/currency/tables_test.go
generated
vendored
Normal file
93
vendor/golang.org/x/text/currency/tables_test.go
generated
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
package currency
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"golang.org/x/text/internal/gen"
|
||||
"golang.org/x/text/internal/testtext"
|
||||
"golang.org/x/text/language"
|
||||
"golang.org/x/text/message"
|
||||
"golang.org/x/text/unicode/cldr"
|
||||
)
|
||||
|
||||
var draft = flag.String("draft",
|
||||
"contributed",
|
||||
`Minimal draft requirements (approved, contributed, provisional, unconfirmed).`)
|
||||
|
||||
func TestTables(t *testing.T) {
|
||||
testtext.SkipIfNotLong(t)
|
||||
|
||||
// Read the CLDR zip file.
|
||||
r := gen.OpenCLDRCoreZip()
|
||||
defer r.Close()
|
||||
|
||||
d := &cldr.Decoder{}
|
||||
d.SetDirFilter("supplemental", "main")
|
||||
d.SetSectionFilter("numbers")
|
||||
data, err := d.DecodeZip(r)
|
||||
if err != nil {
|
||||
t.Fatalf("DecodeZip: %v", err)
|
||||
}
|
||||
|
||||
dr, err := cldr.ParseDraft(*draft)
|
||||
if err != nil {
|
||||
t.Fatalf("filter: %v", err)
|
||||
}
|
||||
|
||||
for _, lang := range data.Locales() {
|
||||
p := message.NewPrinter(language.MustParse(lang))
|
||||
|
||||
ldml := data.RawLDML(lang)
|
||||
if ldml.Numbers == nil || ldml.Numbers.Currencies == nil {
|
||||
continue
|
||||
}
|
||||
for _, c := range ldml.Numbers.Currencies.Currency {
|
||||
syms := cldr.MakeSlice(&c.Symbol)
|
||||
syms.SelectDraft(dr)
|
||||
|
||||
for _, sym := range c.Symbol {
|
||||
cur, err := ParseISO(c.Type)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
formatter := Symbol
|
||||
switch sym.Alt {
|
||||
case "":
|
||||
case "narrow":
|
||||
formatter = NarrowSymbol
|
||||
default:
|
||||
continue
|
||||
}
|
||||
want := sym.Data()
|
||||
if got := p.Sprint(formatter(cur)); got != want {
|
||||
t.Errorf("%s:%sSymbol(%s) = %s; want %s", lang, strings.Title(sym.Alt), c.Type, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, reg := range data.Supplemental().CurrencyData.Region {
|
||||
i := 0
|
||||
for ; regionData[i].Region().String() != reg.Iso3166; i++ {
|
||||
}
|
||||
it := Query(Historical, NonTender, Region(language.MustParseRegion(reg.Iso3166)))
|
||||
for _, cur := range reg.Currency {
|
||||
from, _ := time.Parse("2006-01-02", cur.From)
|
||||
to, _ := time.Parse("2006-01-02", cur.To)
|
||||
|
||||
it.Next()
|
||||
for j, r := range []QueryIter{&iter{regionInfo: ®ionData[i]}, it} {
|
||||
if got, _ := r.From(); from != got {
|
||||
t.Errorf("%d:%s:%s:from: got %v; want %v", j, reg.Iso3166, cur.Iso4217, got, from)
|
||||
}
|
||||
if got, _ := r.To(); to != got {
|
||||
t.Errorf("%d:%s:%s:to: got %v; want %v", j, reg.Iso3166, cur.Iso4217, got, to)
|
||||
}
|
||||
}
|
||||
i++
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user