github.com/tawesoft/golib/v2@v2.10.0/legacy/humanize/factor.go (about)

     1  package humanize
     2  
     3  // Factors describes a way to format a quantity with units.
     4  type Factors struct{
     5      // Factors is a list of Factor entries in ascending order of magnitude.
     6      Factors []Factor
     7  
     8      // Components controls how the formatting is broken up. If set to zero or
     9      // one, formatting has a single component e.g. "1.5 M". If set to two or
    10      // more, formatting is broken up into previous factors e.g. "1 h 50 min"
    11      // (with 2 components) or "1 h 50 min 25 s" (with 3 components).
    12      Components int
    13  }
    14  
    15  // Factor defines one entry in an ordered list of Factors.
    16  type Factor struct{
    17  
    18      // Magnitude defines the absolute size of the factor e.g. 1000000 for the
    19      // SI unit prefix "M".
    20      Magnitude float64
    21  
    22      // Label describes the magnitude, usually as a unit prefix (like SI "M")
    23      // or as a replacement (like "min"), controlled by Mode.
    24      Unit Unit
    25  
    26      // Mode controls the formatting of this factor
    27      Mode FactorMode
    28  }
    29  
    30  // FactorMode controls the formatting of a factor.
    31  type FactorMode int
    32  
    33  const (
    34      // FactorModeIdentity indicates that the given factor label represents the
    35      // unit with no changes. For example, if you're talking about distance in
    36      // metres, FactorModeIdentity means that the current factor is measured in
    37      // metres and not millimetres, or kilometres.
    38      FactorModeIdentity   = FactorMode(0)
    39  
    40      // FactorModeUnitPrefix indicates the given factor label is a unit prefix
    41      // e.g. "Ki" is a byte prefix giving "KiB".
    42      FactorModeUnitPrefix = FactorMode(1)
    43  
    44      // FactorModeReplace indicates the given factor label replaces the current
    45      // unit e.g. the duration of time 100 s becomes 1 min 40 s, not 1 hs
    46      // (which would read as a "hectosecond"!).
    47      FactorModeReplace    = FactorMode(2)
    48  
    49      // FactorModeInputCompat indicates that the given factor label should only
    50      // be considered on input. This may be combined with any other FactorMode
    51      // by a bitwise OR operation. For example, when measuring distance,
    52      // you might accept based on context that "K" probably refers to the
    53      // "kilo"-prefix, not a Kelvin-metre!
    54      FactorModeInputCompat = FactorMode(4)
    55  )
    56  
    57  // Min returns the index of the first Factor greater or equal to n. If n is
    58  // smaller than the first Factor, returns the first Factor instead. Ignores all
    59  // factors that have mode FactorModeInputCompat.
    60  func (f Factors) Min(n float64) int {
    61      if len(f.Factors) == 0 { panic("empty list of factors") }
    62  
    63      if n < f.Factors[0].Magnitude { return 0 }
    64  
    65      for i, factor := range f.Factors[1:] {
    66          if factor.Mode & FactorModeInputCompat == FactorModeInputCompat {
    67              continue // skip
    68          }
    69  
    70          if n < factor.Magnitude {
    71              return i
    72          }
    73      }
    74  
    75      return len(f.Factors) - 1
    76  }