...
1
2
3
4
5
6
7
8
9
10
11 package 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
22
23
24
25
26
27
28
29
30 type Kind struct {
31 rounding rounding
32
33 }
34
35 type rounding byte
36
37 const (
38 standard rounding = iota
39 cash
40 )
41
42 var (
43
44 Standard Kind = Kind{rounding: standard}
45
46
47 Cash Kind = Kind{rounding: cash}
48
49
50 Accounting Kind = Kind{rounding: standard}
51 )
52
53
54
55
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
68 type Unit struct {
69 index uint16
70 }
71
72
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
81 func (u Unit) Amount(amount interface{}) Amount {
82
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
92
93 func ParseISO(s string) (Unit, error) {
94 var buf [4]byte
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
109
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
119
120
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
133
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
148 XXX Unit = Unit{}
149 XTS Unit = Unit{xts}
150
151
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
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
181 XAG Unit = Unit{xag}
182 XAU Unit = Unit{xau}
183 XPT Unit = Unit{xpt}
184 XPD Unit = Unit{xpd}
185 )
186
View as plain text