gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

rules.go (8577B)


      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 }