...
Tawesoft Logo

Source file src/tawesoft.co.uk/go/humanizex/format.go

Documentation: src/tawesoft.co.uk/go/humanizex/format.go

     1  package humanizex
     2  
     3  import (
     4      "math"
     5      "strings"
     6  )
     7  
     8  // FormatParts is a general purpose locale-aware way to format any quantity
     9  // with a defined set of factors into a list of parts. The unit argument is the
    10  // base unit e.g. s for seconds, m for meters, B for bytes. In the simple case
    11  // a list of only one Part is returned, e.g. a Part representing 1.5 km. In
    12  // other cases, there may be multiple parts e.g. the two parts "1 h" and
    13  // "30 min" making up the time "1 h 30 min". The number of parts returned is
    14  // never more than that defined by the factors argument's Components field
    15  // (but may be fewer).
    16  func FormatParts(n float64, unit Unit, factors Factors) []Part {
    17  
    18      numComponents := factors.Components
    19      if numComponents == 0 { numComponents = 1 }
    20  
    21      parts := make([]Part, 0, numComponents)
    22  
    23      for i := 0; i < numComponents; i++ {
    24          factorIdx := factors.bracket(n)
    25          factor := factors.Factors[factorIdx]
    26  
    27          part := Part{
    28              Magnitude: n / factor.Magnitude,
    29              Unit:      factor.Unit,
    30          }
    31  
    32          // skip if not the only non-zero component, but zero magnitude
    33          const epsilon = 0.01
    34          if (part.Magnitude < epsilon) && (len(parts) > 0) {
    35              continue
    36          }
    37  
    38          if i == numComponents - 1 { // last?
    39              if factor.Mode & FactorModeUnitPrefix == FactorModeUnitPrefix {
    40                  part.Unit = part.Unit.Cat(unit)
    41              } else if factor.Mode & FactorModeReplace == FactorModeReplace {
    42                  part.Unit = factor.Unit
    43              } else {
    44                  part.Unit = unit
    45              }
    46          } else {
    47              int, frac := math.Modf(part.Magnitude)
    48              part.Magnitude = int
    49              n = frac * factor.Magnitude
    50          }
    51  
    52          parts = append(parts, part)
    53      }
    54  
    55      return parts
    56  }
    57  
    58  func (h *humanizer) Format(n float64, unit Unit, factors Factors) String {
    59      resultUtf8  := make([]string, 0, factors.Components)
    60      resultAscii := make([]string, 0, factors.Components)
    61      parts := FormatParts(n, unit, factors)
    62  
    63      for _, part := range parts {
    64  
    65          places := 0
    66  
    67          if part.Magnitude < 10.0 {
    68              places = 1
    69          }
    70  
    71          if part.Magnitude < 1.0 {
    72              places = 2
    73          }
    74  
    75          _, frac := math.Modf(part.Magnitude)
    76          if math.Abs(frac) < 0.01 {
    77              places = 0
    78          }
    79  
    80          str := h.Printer.Sprintf("%.*f", places, part.Magnitude)
    81          resultUtf8 = append(resultUtf8, str, part.Unit.Utf8)
    82          resultAscii = append(resultAscii, str, part.Unit.Ascii)
    83      }
    84  
    85      return String{
    86          strings.Join(resultUtf8, " "),
    87          strings.Join(resultAscii, " "),
    88      }
    89  }
    90  
    91  

View as plain text