diff options
Diffstat (limited to 'vendor/golang.org/x/text/internal/number/pattern.go')
-rw-r--r-- | vendor/golang.org/x/text/internal/number/pattern.go | 92 |
1 files changed, 75 insertions, 17 deletions
diff --git a/vendor/golang.org/x/text/internal/number/pattern.go b/vendor/golang.org/x/text/internal/number/pattern.go index ef7f087fe..b95ca40e8 100644 --- a/vendor/golang.org/x/text/internal/number/pattern.go +++ b/vendor/golang.org/x/text/internal/number/pattern.go @@ -39,31 +39,84 @@ import ( // // This type is only intended for internal use. type Pattern struct { - // TODO: this struct can be packed a lot better than it is now. Should be - // possible to make it 32 bytes. - - Affix string // includes prefix and suffix. First byte is prefix length. - Offset uint16 // Offset into Affix for prefix and suffix - NegOffset uint16 // Offset into Affix for negative prefix and suffix or 0. + RoundingContext + Affix string // includes prefix and suffix. First byte is prefix length. + Offset uint16 // Offset into Affix for prefix and suffix + NegOffset uint16 // Offset into Affix for negative prefix and suffix or 0. + PadRune rune FormatWidth uint16 - RoundIncrement uint32 // Use Min*Digits to determine scale - PadRune rune - DigitShift uint8 // Number of decimals to shift. Used for % and ‰. - GroupingSize [2]uint8 Flags PatternFlag +} + +// A RoundingContext indicates how a number should be converted to digits. +// It contains all information needed to determine the "visible digits" as +// required by the pluralization rules. +type RoundingContext struct { + // TODO: unify these two fields so that there is a more unambiguous meaning + // of how precision is handled. + MaxSignificantDigits int16 // -1 is unlimited + MaxFractionDigits int16 // -1 is unlimited + + Increment uint32 + IncrementScale uint8 // May differ from printed scale. + + Mode RoundingMode + + DigitShift uint8 // Number of decimals to shift. Used for % and ‰. // Number of digits. - // TODO: consider using uint32 - MinIntegerDigits uint8 + MinIntegerDigits uint8 + MaxIntegerDigits uint8 MinFractionDigits uint8 - MaxFractionDigits uint8 MinSignificantDigits uint8 - MaxSignificantDigits uint8 - MinExponentDigits uint8 + + MinExponentDigits uint8 +} + +// RoundSignificantDigits returns the number of significant digits an +// implementation of Convert may round to or n < 0 if there is no maximum or +// a maximum is not recommended. +func (r *RoundingContext) RoundSignificantDigits() (n int) { + if r.MaxFractionDigits == 0 && r.MaxSignificantDigits > 0 { + return int(r.MaxSignificantDigits) + } else if r.isScientific() && r.MaxIntegerDigits == 1 { + if r.MaxSignificantDigits == 0 || + int(r.MaxFractionDigits+1) == int(r.MaxSignificantDigits) { + // Note: don't add DigitShift: it is only used for decimals. + return int(r.MaxFractionDigits) + 1 + } + } + return -1 +} + +// RoundFractionDigits returns the number of fraction digits an implementation +// of Convert may round to or n < 0 if there is no maximum or a maximum is not +// recommended. +func (r *RoundingContext) RoundFractionDigits() (n int) { + if r.MinExponentDigits == 0 && + r.MaxSignificantDigits == 0 && + r.MaxFractionDigits >= 0 { + return int(r.MaxFractionDigits) + int(r.DigitShift) + } + return -1 +} + +// SetScale fixes the RoundingContext to a fixed number of fraction digits. +func (r *RoundingContext) SetScale(scale int) { + r.MinFractionDigits = uint8(scale) + r.MaxFractionDigits = int16(scale) +} + +func (r *RoundingContext) SetPrecision(prec int) { + r.MaxSignificantDigits = int16(prec) +} + +func (r *RoundingContext) isScientific() bool { + return r.MinExponentDigits > 0 } func (f *Pattern) needsSep(pos int) bool { @@ -177,6 +230,9 @@ func ParsePattern(s string) (f *Pattern, err error) { } else { p.Affix = affix } + if p.Increment == 0 { + p.IncrementScale = 0 + } return p.Pattern, nil } @@ -302,6 +358,7 @@ func (p *parser) number(r rune) state { case '@': p.groupingCount++ p.leadingSharps = 0 + p.MaxFractionDigits = -1 return p.sigDigits(r) case ',': if p.leadingSharps == 0 { // no leading commas @@ -339,7 +396,7 @@ func (p *parser) integer(r rune) state { p.updateGrouping() return next } - p.RoundIncrement = p.RoundIncrement*10 + uint32(r-'0') + p.Increment = p.Increment*10 + uint32(r-'0') p.groupingCount++ p.MinIntegerDigits++ return p.integer @@ -389,7 +446,8 @@ func (p *parser) normalizeSigDigitsWithExponent() state { func (p *parser) fraction(r rune) state { switch r { case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - p.RoundIncrement = p.RoundIncrement*10 + uint32(r-'0') + p.Increment = p.Increment*10 + uint32(r-'0') + p.IncrementScale++ p.MinFractionDigits++ p.MaxFractionDigits++ case '#': |