diff options
author | Rutger Broekhoff | 2023-12-29 21:31:53 +0100 |
---|---|---|
committer | Rutger Broekhoff | 2023-12-29 21:31:53 +0100 |
commit | 404aeae4545d2426c089a5f8d5e82dae56f5212b (patch) | |
tree | 2d84e00af272b39fc04f3795ae06bc48970e57b5 /vendor/github.com/dustin/go-humanize/si.go | |
parent | 209d8b0187ed025dec9ac149ebcced3462877bff (diff) | |
download | gitolfs3-404aeae4545d2426c089a5f8d5e82dae56f5212b.tar.gz gitolfs3-404aeae4545d2426c089a5f8d5e82dae56f5212b.zip |
Make Nix builds work
Diffstat (limited to 'vendor/github.com/dustin/go-humanize/si.go')
-rw-r--r-- | vendor/github.com/dustin/go-humanize/si.go | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/vendor/github.com/dustin/go-humanize/si.go b/vendor/github.com/dustin/go-humanize/si.go new file mode 100644 index 0000000..8b85019 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/si.go | |||
@@ -0,0 +1,127 @@ | |||
1 | package humanize | ||
2 | |||
3 | import ( | ||
4 | "errors" | ||
5 | "math" | ||
6 | "regexp" | ||
7 | "strconv" | ||
8 | ) | ||
9 | |||
10 | var siPrefixTable = map[float64]string{ | ||
11 | -30: "q", // quecto | ||
12 | -27: "r", // ronto | ||
13 | -24: "y", // yocto | ||
14 | -21: "z", // zepto | ||
15 | -18: "a", // atto | ||
16 | -15: "f", // femto | ||
17 | -12: "p", // pico | ||
18 | -9: "n", // nano | ||
19 | -6: "ยต", // micro | ||
20 | -3: "m", // milli | ||
21 | 0: "", | ||
22 | 3: "k", // kilo | ||
23 | 6: "M", // mega | ||
24 | 9: "G", // giga | ||
25 | 12: "T", // tera | ||
26 | 15: "P", // peta | ||
27 | 18: "E", // exa | ||
28 | 21: "Z", // zetta | ||
29 | 24: "Y", // yotta | ||
30 | 27: "R", // ronna | ||
31 | 30: "Q", // quetta | ||
32 | } | ||
33 | |||
34 | var revSIPrefixTable = revfmap(siPrefixTable) | ||
35 | |||
36 | // revfmap reverses the map and precomputes the power multiplier | ||
37 | func revfmap(in map[float64]string) map[string]float64 { | ||
38 | rv := map[string]float64{} | ||
39 | for k, v := range in { | ||
40 | rv[v] = math.Pow(10, k) | ||
41 | } | ||
42 | return rv | ||
43 | } | ||
44 | |||
45 | var riParseRegex *regexp.Regexp | ||
46 | |||
47 | func init() { | ||
48 | ri := `^([\-0-9.]+)\s?([` | ||
49 | for _, v := range siPrefixTable { | ||
50 | ri += v | ||
51 | } | ||
52 | ri += `]?)(.*)` | ||
53 | |||
54 | riParseRegex = regexp.MustCompile(ri) | ||
55 | } | ||
56 | |||
57 | // ComputeSI finds the most appropriate SI prefix for the given number | ||
58 | // and returns the prefix along with the value adjusted to be within | ||
59 | // that prefix. | ||
60 | // | ||
61 | // See also: SI, ParseSI. | ||
62 | // | ||
63 | // e.g. ComputeSI(2.2345e-12) -> (2.2345, "p") | ||
64 | func ComputeSI(input float64) (float64, string) { | ||
65 | if input == 0 { | ||
66 | return 0, "" | ||
67 | } | ||
68 | mag := math.Abs(input) | ||
69 | exponent := math.Floor(logn(mag, 10)) | ||
70 | exponent = math.Floor(exponent/3) * 3 | ||
71 | |||
72 | value := mag / math.Pow(10, exponent) | ||
73 | |||
74 | // Handle special case where value is exactly 1000.0 | ||
75 | // Should return 1 M instead of 1000 k | ||
76 | if value == 1000.0 { | ||
77 | exponent += 3 | ||
78 | value = mag / math.Pow(10, exponent) | ||
79 | } | ||
80 | |||
81 | value = math.Copysign(value, input) | ||
82 | |||
83 | prefix := siPrefixTable[exponent] | ||
84 | return value, prefix | ||
85 | } | ||
86 | |||
87 | // SI returns a string with default formatting. | ||
88 | // | ||
89 | // SI uses Ftoa to format float value, removing trailing zeros. | ||
90 | // | ||
91 | // See also: ComputeSI, ParseSI. | ||
92 | // | ||
93 | // e.g. SI(1000000, "B") -> 1 MB | ||
94 | // e.g. SI(2.2345e-12, "F") -> 2.2345 pF | ||
95 | func SI(input float64, unit string) string { | ||
96 | value, prefix := ComputeSI(input) | ||
97 | return Ftoa(value) + " " + prefix + unit | ||
98 | } | ||
99 | |||
100 | // SIWithDigits works like SI but limits the resulting string to the | ||
101 | // given number of decimal places. | ||
102 | // | ||
103 | // e.g. SIWithDigits(1000000, 0, "B") -> 1 MB | ||
104 | // e.g. SIWithDigits(2.2345e-12, 2, "F") -> 2.23 pF | ||
105 | func SIWithDigits(input float64, decimals int, unit string) string { | ||
106 | value, prefix := ComputeSI(input) | ||
107 | return FtoaWithDigits(value, decimals) + " " + prefix + unit | ||
108 | } | ||
109 | |||
110 | var errInvalid = errors.New("invalid input") | ||
111 | |||
112 | // ParseSI parses an SI string back into the number and unit. | ||
113 | // | ||
114 | // See also: SI, ComputeSI. | ||
115 | // | ||
116 | // e.g. ParseSI("2.2345 pF") -> (2.2345e-12, "F", nil) | ||
117 | func ParseSI(input string) (float64, string, error) { | ||
118 | found := riParseRegex.FindStringSubmatch(input) | ||
119 | if len(found) != 4 { | ||
120 | return 0, "", errInvalid | ||
121 | } | ||
122 | mag := revSIPrefixTable[found[2]] | ||
123 | unit := found[3] | ||
124 | |||
125 | base, err := strconv.ParseFloat(found[1], 64) | ||
126 | return base * mag, unit, err | ||
127 | } | ||