...

Source file src/github.com/go-playground/locales/rules.go

Documentation: github.com/go-playground/locales

     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  }
   294  

View as plain text