github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/vendor_skip/golang.org/x/text/number/option.go (about) 1 // Copyright 2017 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package number 6 7 import ( 8 "fmt" 9 10 "golang.org/x/text/internal/number" 11 "golang.org/x/text/language" 12 ) 13 14 // An Option configures a Formatter. 15 type Option option 16 17 type option func(tag language.Tag, f *number.Formatter) 18 19 // TODO: SpellOut requires support of the ICU RBNF format. 20 // func SpellOut() Option 21 22 // NoSeparator causes a number to be displayed without grouping separators. 23 func NoSeparator() Option { 24 return func(t language.Tag, f *number.Formatter) { 25 f.GroupingSize = [2]uint8{} 26 } 27 } 28 29 // MaxIntegerDigits limits the number of integer digits, eliminating the 30 // most significant digits. 31 func MaxIntegerDigits(max int) Option { 32 return func(t language.Tag, f *number.Formatter) { 33 if max >= 1<<8 { 34 max = (1 << 8) - 1 35 } 36 f.MaxIntegerDigits = uint8(max) 37 } 38 } 39 40 // MinIntegerDigits specifies the minimum number of integer digits, adding 41 // leading zeros when needed. 42 func MinIntegerDigits(min int) Option { 43 return func(t language.Tag, f *number.Formatter) { 44 if min >= 1<<8 { 45 min = (1 << 8) - 1 46 } 47 f.MinIntegerDigits = uint8(min) 48 } 49 } 50 51 // MaxFractionDigits specifies the maximum number of fractional digits. 52 func MaxFractionDigits(max int) Option { 53 return func(t language.Tag, f *number.Formatter) { 54 if max >= 1<<15 { 55 max = (1 << 15) - 1 56 } 57 f.MaxFractionDigits = int16(max) 58 } 59 } 60 61 // MinFractionDigits specifies the minimum number of fractional digits. 62 func MinFractionDigits(min int) Option { 63 return func(t language.Tag, f *number.Formatter) { 64 if min >= 1<<8 { 65 min = (1 << 8) - 1 66 } 67 f.MinFractionDigits = uint8(min) 68 } 69 } 70 71 // Precision sets the maximum number of significant digits. A negative value 72 // means exact. 73 func Precision(prec int) Option { 74 return func(t language.Tag, f *number.Formatter) { 75 f.SetPrecision(prec) 76 } 77 } 78 79 // Scale simultaneously sets MinFractionDigits and MaxFractionDigits to the 80 // given value. 81 func Scale(decimals int) Option { 82 return func(t language.Tag, f *number.Formatter) { 83 f.SetScale(decimals) 84 } 85 } 86 87 // IncrementString sets the incremental value to which numbers should be 88 // rounded. For instance: Increment("0.05") will cause 1.44 to round to 1.45. 89 // IncrementString also sets scale to the scale of the increment. 90 func IncrementString(decimal string) Option { 91 increment := 0 92 scale := 0 93 d := decimal 94 p := 0 95 for ; p < len(d) && '0' <= d[p] && d[p] <= '9'; p++ { 96 increment *= 10 97 increment += int(d[p]) - '0' 98 } 99 if p < len(d) && d[p] == '.' { 100 for p++; p < len(d) && '0' <= d[p] && d[p] <= '9'; p++ { 101 increment *= 10 102 increment += int(d[p]) - '0' 103 scale++ 104 } 105 } 106 if p < len(d) { 107 increment = 0 108 scale = 0 109 } 110 return func(t language.Tag, f *number.Formatter) { 111 f.Increment = uint32(increment) 112 f.IncrementScale = uint8(scale) 113 f.SetScale(scale) 114 } 115 } 116 117 func noop(language.Tag, *number.Formatter) {} 118 119 // PatternOverrides allows users to specify alternative patterns for specific 120 // languages. The Pattern will be overridden for all languages in a subgroup as 121 // well. The function will panic for invalid input. It is best to create this 122 // option at startup time. 123 // PatternOverrides must be the first Option passed to a formatter. 124 func PatternOverrides(patterns map[string]string) Option { 125 // TODO: make it so that it does not have to be the first option. 126 // TODO: use -x-nochild to indicate it does not override child tags. 127 m := map[language.Tag]*number.Pattern{} 128 for k, v := range patterns { 129 tag := language.MustParse(k) 130 p, err := number.ParsePattern(v) 131 if err != nil { 132 panic(fmt.Errorf("number: PatternOverrides: %v", err)) 133 } 134 m[tag] = p 135 } 136 return func(t language.Tag, f *number.Formatter) { 137 // TODO: Use language grouping relation instead of parent relation. 138 // TODO: Should parent implement the grouping relation? 139 for lang := t; ; lang = t.Parent() { 140 if p, ok := m[lang]; ok { 141 f.Pattern = *p 142 break 143 } 144 if lang == language.Und { 145 break 146 } 147 } 148 } 149 } 150 151 // FormatWidth sets the total format width. 152 func FormatWidth(n int) Option { 153 if n <= 0 { 154 return noop 155 } 156 return func(t language.Tag, f *number.Formatter) { 157 f.FormatWidth = uint16(n) 158 if f.PadRune == 0 { 159 f.PadRune = ' ' 160 } 161 } 162 } 163 164 // Pad sets the rune to be used for filling up to the format width. 165 func Pad(r rune) Option { 166 return func(t language.Tag, f *number.Formatter) { 167 f.PadRune = r 168 } 169 } 170 171 // TODO: 172 // - FormatPosition (using type aliasing?) 173 // - Multiplier: find a better way to represent and figure out what to do 174 // with clashes with percent/permille. 175 // - NumberingSystem(nu string): not accessible in number.Info now. Also, should 176 // this be keyed by language or generic? 177 // - SymbolOverrides(symbols map[string]map[number.SymbolType]string) Option