summaryrefslogtreecommitdiffstats
path: root/vendor/golang.org/x/text/internal/number/pattern.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/text/internal/number/pattern.go')
-rw-r--r--vendor/golang.org/x/text/internal/number/pattern.go92
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 '#':