OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / go-playground / locales / rules.go
1 package locales
2
3 import (
4         "strconv"
5         "time"
6
7         "github.com/go-playground/locales/currency"
8 )
9
10 // // ErrBadNumberValue is returned when the number passed for
11 // // plural rule determination cannot be parsed
12 // type ErrBadNumberValue struct {
13 //      NumberValue string
14 //      InnerError  error
15 // }
16
17 // // Error returns ErrBadNumberValue error string
18 // func (e *ErrBadNumberValue) Error() string {
19 //      return fmt.Sprintf("Invalid Number Value '%s' %s", e.NumberValue, e.InnerError)
20 // }
21
22 // var _ error = new(ErrBadNumberValue)
23
24 // PluralRule denotes the type of plural rules
25 type PluralRule int
26
27 // PluralRule's
28 const (
29         PluralRuleUnknown PluralRule = iota
30         PluralRuleZero               // zero
31         PluralRuleOne                // one - singular
32         PluralRuleTwo                // two - dual
33         PluralRuleFew                // few - paucal
34         PluralRuleMany               // many - also used for fractions if they have a separate class
35         PluralRuleOther              // other - required—general plural form—also used if the language only has a single form
36 )
37
38 const (
39         pluralsString = "UnknownZeroOneTwoFewManyOther"
40 )
41
42 // Translator encapsulates an instance of a locale
43 // NOTE: some values are returned as a []byte just in case the caller
44 // wishes to add more and can help avoid allocations; otherwise just cast as string
45 type Translator interface {
46
47         // The following Functions are for overriding, debugging or developing
48         // with a Translator Locale
49
50         // Locale returns the string value of the translator
51         Locale() string
52
53         // returns an array of cardinal plural rules associated
54         // with this translator
55         PluralsCardinal() []PluralRule
56
57         // returns an array of ordinal plural rules associated
58         // with this translator
59         PluralsOrdinal() []PluralRule
60
61         // returns an array of range plural rules associated
62         // with this translator
63         PluralsRange() []PluralRule
64
65         // returns the cardinal PluralRule given 'num' and digits/precision of 'v' for locale
66         CardinalPluralRule(num float64, v uint64) PluralRule
67
68         // returns the ordinal PluralRule given 'num' and digits/precision of 'v' for locale
69         OrdinalPluralRule(num float64, v uint64) PluralRule
70
71         // returns the ordinal PluralRule given 'num1', 'num2' and digits/precision of 'v1' and 'v2' for locale
72         RangePluralRule(num1 float64, v1 uint64, num2 float64, v2 uint64) PluralRule
73
74         // returns the locales abbreviated month given the 'month' provided
75         MonthAbbreviated(month time.Month) string
76
77         // returns the locales abbreviated months
78         MonthsAbbreviated() []string
79
80         // returns the locales narrow month given the 'month' provided
81         MonthNarrow(month time.Month) string
82
83         // returns the locales narrow months
84         MonthsNarrow() []string
85
86         // returns the locales wide month given the 'month' provided
87         MonthWide(month time.Month) string
88
89         // returns the locales wide months
90         MonthsWide() []string
91
92         // returns the locales abbreviated weekday given the 'weekday' provided
93         WeekdayAbbreviated(weekday time.Weekday) string
94
95         // returns the locales abbreviated weekdays
96         WeekdaysAbbreviated() []string
97
98         // returns the locales narrow weekday given the 'weekday' provided
99         WeekdayNarrow(weekday time.Weekday) string
100
101         // WeekdaysNarrowreturns the locales narrow weekdays
102         WeekdaysNarrow() []string
103
104         // returns the locales short weekday given the 'weekday' provided
105         WeekdayShort(weekday time.Weekday) string
106
107         // returns the locales short weekdays
108         WeekdaysShort() []string
109
110         // returns the locales wide weekday given the 'weekday' provided
111         WeekdayWide(weekday time.Weekday) string
112
113         // returns the locales wide weekdays
114         WeekdaysWide() []string
115
116         // The following Functions are common Formatting functionsfor the Translator's Locale
117
118         // returns 'num' with digits/precision of 'v' for locale and handles both Whole and Real numbers based on 'v'
119         FmtNumber(num float64, v uint64) string
120
121         // returns 'num' with digits/precision of 'v' for locale and handles both Whole and Real numbers based on 'v'
122         // NOTE: 'num' passed into FmtPercent is assumed to be in percent already
123         FmtPercent(num float64, v uint64) string
124
125         // returns the currency representation of 'num' with digits/precision of 'v' for locale
126         FmtCurrency(num float64, v uint64, currency currency.Type) string
127
128         // returns the currency representation of 'num' with digits/precision of 'v' for locale
129         // in accounting notation.
130         FmtAccounting(num float64, v uint64, currency currency.Type) string
131
132         // returns the short date representation of 't' for locale
133         FmtDateShort(t time.Time) string
134
135         // returns the medium date representation of 't' for locale
136         FmtDateMedium(t time.Time) string
137
138         //  returns the long date representation of 't' for locale
139         FmtDateLong(t time.Time) string
140
141         // returns the full date representation of 't' for locale
142         FmtDateFull(t time.Time) string
143
144         // returns the short time representation of 't' for locale
145         FmtTimeShort(t time.Time) string
146
147         // returns the medium time representation of 't' for locale
148         FmtTimeMedium(t time.Time) string
149
150         // returns the long time representation of 't' for locale
151         FmtTimeLong(t time.Time) string
152
153         // returns the full time representation of 't' for locale
154         FmtTimeFull(t time.Time) string
155 }
156
157 // String returns the string value  of PluralRule
158 func (p PluralRule) String() string {
159
160         switch p {
161         case PluralRuleZero:
162                 return pluralsString[7:11]
163         case PluralRuleOne:
164                 return pluralsString[11:14]
165         case PluralRuleTwo:
166                 return pluralsString[14:17]
167         case PluralRuleFew:
168                 return pluralsString[17:20]
169         case PluralRuleMany:
170                 return pluralsString[20:24]
171         case PluralRuleOther:
172                 return pluralsString[24:]
173         default:
174                 return pluralsString[:7]
175         }
176 }
177
178 //
179 // Precision Notes:
180 //
181 // must specify a precision >= 0, and here is why https://play.golang.org/p/LyL90U0Vyh
182 //
183 //      v := float64(3.141)
184 //      i := float64(int64(v))
185 //
186 //      fmt.Println(v - i)
187 //
188 //      or
189 //
190 //      s := strconv.FormatFloat(v-i, 'f', -1, 64)
191 //      fmt.Println(s)
192 //
193 // these will not print what you'd expect: 0.14100000000000001
194 // and so this library requires a precision to be specified, or
195 // inaccurate plural rules could be applied.
196 //
197 //
198 //
199 // n - absolute value of the source number (integer and decimals).
200 // i - integer digits of n.
201 // v - number of visible fraction digits in n, with trailing zeros.
202 // w - number of visible fraction digits in n, without trailing zeros.
203 // f - visible fractional digits in n, with trailing zeros.
204 // t - visible fractional digits in n, without trailing zeros.
205 //
206 //
207 // Func(num float64, v uint64) // v = digits/precision and prevents -1 as a special case as this can lead to very unexpected behaviour, see precision note's above.
208 //
209 // n := math.Abs(num)
210 // i := int64(n)
211 // v := v
212 //
213 //
214 // w := strconv.FormatFloat(num-float64(i), 'f', int(v), 64)  // then parse backwards on string until no more zero's....
215 // f := strconv.FormatFloat(n, 'f', int(v), 64)                           // then turn everything after decimal into an int64
216 // t := strconv.FormatFloat(n, 'f', int(v), 64)                           // then parse backwards on string until no more zero's....
217 //
218 //
219 //
220 // General Inclusion Rules
221 // - v will always be available inherently
222 // - all require n
223 // - w requires i
224 //
225
226 // W returns the number of visible fraction digits in N, without trailing zeros.
227 func W(n float64, v uint64) (w int64) {
228
229         s := strconv.FormatFloat(n-float64(int64(n)), 'f', int(v), 64)
230
231         // with either be '0' or '0.xxxx', so if 1 then w will be zero
232         // otherwise need to parse
233         if len(s) != 1 {
234
235                 s = s[2:]
236                 end := len(s) + 1
237
238                 for i := end; i >= 0; i-- {
239                         if s[i] != '0' {
240                                 end = i + 1
241                                 break
242                         }
243                 }
244
245                 w = int64(len(s[:end]))
246         }
247
248         return
249 }
250
251 // F returns the visible fractional digits in N, with trailing zeros.
252 func F(n float64, v uint64) (f int64) {
253
254         s := strconv.FormatFloat(n-float64(int64(n)), 'f', int(v), 64)
255
256         // with either be '0' or '0.xxxx', so if 1 then f will be zero
257         // otherwise need to parse
258         if len(s) != 1 {
259
260                 // ignoring error, because it can't fail as we generated
261                 // the string internally from a real number
262                 f, _ = strconv.ParseInt(s[2:], 10, 64)
263         }
264
265         return
266 }
267
268 // T returns the visible fractional digits in N, without trailing zeros.
269 func T(n float64, v uint64) (t int64) {
270
271         s := strconv.FormatFloat(n-float64(int64(n)), 'f', int(v), 64)
272
273         // with either be '0' or '0.xxxx', so if 1 then t will be zero
274         // otherwise need to parse
275         if len(s) != 1 {
276
277                 s = s[2:]
278                 end := len(s) + 1
279
280                 for i := end; i >= 0; i-- {
281                         if s[i] != '0' {
282                                 end = i + 1
283                                 break
284                         }
285                 }
286
287                 // ignoring error, because it can't fail as we generated
288                 // the string internally from a real number
289                 t, _ = strconv.ParseInt(s[:end], 10, 64)
290         }
291
292         return
293 }