OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / text / currency / currency.go
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 //go:generate go run gen.go gen_common.go -output tables.go
6
7 // Package currency contains currency-related functionality.
8 //
9 // NOTE: the formatting functionality is currently under development and may
10 // change without notice.
11 package currency // import "golang.org/x/text/currency"
12
13 import (
14         "errors"
15         "sort"
16
17         "golang.org/x/text/internal/tag"
18         "golang.org/x/text/language"
19 )
20
21 // TODO:
22 // - language-specific currency names.
23 // - currency formatting.
24 // - currency information per region
25 // - register currency code (there are no private use area)
26
27 // TODO: remove Currency type from package language.
28
29 // Kind determines the rounding and rendering properties of a currency value.
30 type Kind struct {
31         rounding rounding
32         // TODO: formatting type: standard, accounting. See CLDR.
33 }
34
35 type rounding byte
36
37 const (
38         standard rounding = iota
39         cash
40 )
41
42 var (
43         // Standard defines standard rounding and formatting for currencies.
44         Standard Kind = Kind{rounding: standard}
45
46         // Cash defines rounding and formatting standards for cash transactions.
47         Cash Kind = Kind{rounding: cash}
48
49         // Accounting defines rounding and formatting standards for accounting.
50         Accounting Kind = Kind{rounding: standard}
51 )
52
53 // Rounding reports the rounding characteristics for the given currency, where
54 // scale is the number of fractional decimals and increment is the number of
55 // units in terms of 10^(-scale) to which to round to.
56 func (k Kind) Rounding(cur Unit) (scale, increment int) {
57         info := currency.Elem(int(cur.index))[3]
58         switch k.rounding {
59         case standard:
60                 info &= roundMask
61         case cash:
62                 info >>= cashShift
63         }
64         return int(roundings[info].scale), int(roundings[info].increment)
65 }
66
67 // Unit is an ISO 4217 currency designator.
68 type Unit struct {
69         index uint16
70 }
71
72 // String returns the ISO code of u.
73 func (u Unit) String() string {
74         if u.index == 0 {
75                 return "XXX"
76         }
77         return currency.Elem(int(u.index))[:3]
78 }
79
80 // Amount creates an Amount for the given currency unit and amount.
81 func (u Unit) Amount(amount interface{}) Amount {
82         // TODO: verify amount is a supported number type
83         return Amount{amount: amount, currency: u}
84 }
85
86 var (
87         errSyntax = errors.New("currency: tag is not well-formed")
88         errValue  = errors.New("currency: tag is not a recognized currency")
89 )
90
91 // ParseISO parses a 3-letter ISO 4217 currency code. It returns an error if s
92 // is not well-formed or not a recognized currency code.
93 func ParseISO(s string) (Unit, error) {
94         var buf [4]byte // Take one byte more to detect oversize keys.
95         key := buf[:copy(buf[:], s)]
96         if !tag.FixCase("XXX", key) {
97                 return Unit{}, errSyntax
98         }
99         if i := currency.Index(key); i >= 0 {
100                 if i == xxx {
101                         return Unit{}, nil
102                 }
103                 return Unit{uint16(i)}, nil
104         }
105         return Unit{}, errValue
106 }
107
108 // MustParseISO is like ParseISO, but panics if the given currency unit
109 // cannot be parsed. It simplifies safe initialization of Unit values.
110 func MustParseISO(s string) Unit {
111         c, err := ParseISO(s)
112         if err != nil {
113                 panic(err)
114         }
115         return c
116 }
117
118 // FromRegion reports the currency unit that is currently legal tender in the
119 // given region according to CLDR. It will return false if region currently does
120 // not have a legal tender.
121 func FromRegion(r language.Region) (currency Unit, ok bool) {
122         x := regionToCode(r)
123         i := sort.Search(len(regionToCurrency), func(i int) bool {
124                 return regionToCurrency[i].region >= x
125         })
126         if i < len(regionToCurrency) && regionToCurrency[i].region == x {
127                 return Unit{regionToCurrency[i].code}, true
128         }
129         return Unit{}, false
130 }
131
132 // FromTag reports the most likely currency for the given tag. It considers the
133 // currency defined in the -u extension and infers the region if necessary.
134 func FromTag(t language.Tag) (Unit, language.Confidence) {
135         if cur := t.TypeForKey("cu"); len(cur) == 3 {
136                 c, _ := ParseISO(cur)
137                 return c, language.Exact
138         }
139         r, conf := t.Region()
140         if cur, ok := FromRegion(r); ok {
141                 return cur, conf
142         }
143         return Unit{}, language.No
144 }
145
146 var (
147         // Undefined and testing.
148         XXX Unit = Unit{}
149         XTS Unit = Unit{xts}
150
151         // G10 currencies https://en.wikipedia.org/wiki/G10_currencies.
152         USD Unit = Unit{usd}
153         EUR Unit = Unit{eur}
154         JPY Unit = Unit{jpy}
155         GBP Unit = Unit{gbp}
156         CHF Unit = Unit{chf}
157         AUD Unit = Unit{aud}
158         NZD Unit = Unit{nzd}
159         CAD Unit = Unit{cad}
160         SEK Unit = Unit{sek}
161         NOK Unit = Unit{nok}
162
163         // Additional common currencies as defined by CLDR.
164         BRL Unit = Unit{brl}
165         CNY Unit = Unit{cny}
166         DKK Unit = Unit{dkk}
167         INR Unit = Unit{inr}
168         RUB Unit = Unit{rub}
169         HKD Unit = Unit{hkd}
170         IDR Unit = Unit{idr}
171         KRW Unit = Unit{krw}
172         MXN Unit = Unit{mxn}
173         PLN Unit = Unit{pln}
174         SAR Unit = Unit{sar}
175         THB Unit = Unit{thb}
176         TRY Unit = Unit{try}
177         TWD Unit = Unit{twd}
178         ZAR Unit = Unit{zar}
179
180         // Precious metals.
181         XAG Unit = Unit{xag}
182         XAU Unit = Unit{xau}
183         XPT Unit = Unit{xpt}
184         XPD Unit = Unit{xpd}
185 )