1 package humanizex 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 size. 6 Factors []Factor 7 8 // Components controls how the formatting is broken up - 9 // 10 // - if zero (default) or 1 (interchangeable), formatting has a single 11 // component e.g. "1.5 M". 12 // 13 // - if 2 or more, formatting is broken up into previous factors e.g. 14 // "1 h 50 min" (2 components) or "1 h 50 min 25 s" (3 components) 15 Components int 16 } 17 18 // Factor defines one entry in an ordered list of Factors. 19 type Factor struct{ 20 21 // Magnitude defines the absolute size of the factor e.g. 1000000 for the 22 // SI unit prefix "M". 23 Magnitude float64 24 25 // Label describes the magnitude, usually as a unit prefix (like SI "M") 26 // or as a replacement (like "min"), controlled by Mode. 27 Unit Unit 28 29 // Mode controls the formatting of this factor 30 Mode FactorMode 31 } 32 33 // FactorMode controls the formatting of a factor. 34 type FactorMode int 35 36 const ( 37 // FactorModeIdentity indicates that the given factor label represents the 38 // unit with no changes. 39 FactorModeIdentity = FactorMode(0) 40 41 // FactorModeUnitPrefix indicates the given factor label is a unit prefix 42 // e.g. "Ki" is a byte prefix giving "KiB". 43 FactorModeUnitPrefix = FactorMode(1) 44 45 // FactorModeReplace indicates the given factor label replaces the current 46 // unit e.g. the duration of time 100 s becomes 1 min 40 s, not 1 hs 47 // (hectosecond)! 48 FactorModeReplace = FactorMode(2) 49 50 // FactorModeInputCompat indicates that the given factor label should only 51 // be considered on input. This may be combined with any other FactorMode 52 // by a bitwise OR operation. 53 FactorModeInputCompat = FactorMode(4) 54 ) 55 56 // bracket returns the index of the first Factor greater or equal to n except 57 // if n is smaller than the first Factor, returns the first Factor (zero). 58 // Excludes factors with mode FactorModeInputCompat. 59 func (f Factors) bracket(n float64) int { 60 if len(f.Factors) == 0 { 61 panic("operation not defined on an empty list of factors") 62 } 63 64 if n < f.Factors[0].Magnitude { return 0 } 65 66 for i, factor := range f.Factors[1:] { 67 if factor.Mode & FactorModeInputCompat == FactorModeInputCompat { 68 continue // skip 69 } 70 71 if n < factor.Magnitude { 72 return i 73 } 74 } 75 76 return len(f.Factors) - 1 77 } 78