// Package compactnumber allows for localized CLDR compact number formatting.
package compactnumberimport ()// Formatter is a struct containing a method to format an integer based on the specified language and compaction type.typeFormatterstruct { lang language.Tag compactType CompactType}// FormatterAPI is an interface implemented by Formatter that can be used for mocking purposestypeFormatterAPIinterface {Format(n int, numOptions ...number.Option) (string, error)}// NewFormatter creates a new formatter based on the specified language and compaction type.func ( string, CompactType) Formatter {returnFormatter{lang: language.Make(),compactType: , }}// Format takes in an integer and options and formats it according to the formatter's locale and compaction settings.// Note: this method truncates numbers and does not support fractions (e.g. 11.5M).//// Documented in CLDR spec: http://www.unicode.org/reports/tr35/tr35-numbers.html#Compact_Number_Formatsfunc ( *Formatter) ( int, ...number.Option) (string, error) { = append(, number.Scale(0)) , := compactFormsByLanguage[.lang.String()]if ! {// Fall back to base language , := .lang.Base()if == language.No {return"", errors.New(fmt.Sprintf("no compact forms or fallback for language %s", .lang.String())) } , = compactFormsByLanguage[.String()]if ! {return"", errors.New(fmt.Sprintf("missing compact forms for language %s and fallback %s", .lang.String(), )) } } := [.compactType]// Apply negative modifier at the end if dealing with negative number := 1if < 0 { = -1 *= -1 }// To format a number N, the greatest type less than or equal to N is used, with the appropriate plural category.varmodels.CompactFormRulefor , := range {ifint64() >= .Type { = } else {break } }// N is divided by the type, after removing the number of zeros in the pattern, less 1. := .shortNum(, )// Best effort fetching plural form := .pluralForm() , := .PatternsByPluralForm[]if ! {// Attempt to fall back to catch-all "other" pattern if none for current plural form found = .PatternsByPluralForm["other"] }varerror , = formatPattern()if != nil {return"", }// If the value is precisely “0”, either explicit or defaulted, then the normal number format pattern for that sort of object is supplied := message.NewPrinter(.lang)if == "0" {return .Sprintf("%v", number.Decimal(*, ...)), nil }return .Sprintf(, number.Decimal(*int64(), ...)), nil}// Divides number to be used in compact display according to logic in CLDR spec: http://www.unicode.org/reports/tr35/tr35-numbers.html#Compact_Number_Formatsfunc ( *Formatter) ( int, models.CompactFormRule) int64 { := .Typefor := 0; < .ZeroesInPattern-1; ++ { /= 10 } := int64()if != 0 { /= }return}// Gets the pluralized form of the number, as per CLDR spec: http://cldr.unicode.org/index/cldr-spec/plural-rules// We use gotnospirit/makeplural for this as golang.org/x/text/plural does not expose a suitable PluralForm method.// This is a best effort function since the languages might not match up perfectly between packages.func ( *Formatter) ( interface{}) string { , := .lang.Base()if == language.No {return"other" } , := plural.GetFunc(.String())if != nil {return"other" }return (, false)}// Process CLDR pattern to a format suitable for use in Printer.Sprintf in golang.org/x/text/message.// Documentation for these special characters can be found in the CLDR spec: http://cldr.unicode.org/translation/number-patternsfunc formatPattern( string) (string, error) {// Default to 0 (sentinel value for no pattern)if == "" {return"0", nil }// Default to the first form if there's multiple = strings.Split(, ";")[0]// Remove special pattern symbols, as this formatting is already handled by golang.org/x/text/message = strings.Replace(, "'", "", -1)// Replace all 0s with a single %v for number formatting := strings.IndexRune(, '0')if == -1 {return"", errors.New(fmt.Sprintf("invalid pattern (no digit pattern characters): %s", )) } = strings.Replace(, "0", "", -1) := []rune() := ""if < len() { = string([:]) } = fmt.Sprintf("%s%s%s", string([:]), "%v", )return , nil}
The pages are generated with Goldsv0.8.2. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.