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