-
Notifications
You must be signed in to change notification settings - Fork 0
/
bytes.go
130 lines (122 loc) · 2.99 KB
/
bytes.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package flagx
import (
"flag"
"fmt"
"math"
"strconv"
"strings"
)
// NewBytes returns new `bytes` flag with the given name, defaultValue and description.
func NewBytes(name string, defaultValue int64, description string) *Bytes {
description += "\nSupports the following optional suffixes for `size` values: KB, MB, GB, TB, KiB, MiB, GiB, TiB." + envHelp(name)
b := Bytes{
N: defaultValue,
valueString: fmt.Sprintf("%d", defaultValue),
}
flag.Var(&b, name, description)
return &b
}
// Bytes is a flag for holding size in bytes.
//
// It supports the following optional suffixes for values: KB, MB, GB, TB, KiB, MiB, GiB, TiB.
type Bytes struct {
// N contains parsed value for the given flag.
N int64
valueString string
}
// IntN returns the stored value capped by int type.
func (b *Bytes) IntN() int {
if b.N > math.MaxInt {
return math.MaxInt
}
if b.N < math.MinInt {
return math.MinInt
}
return int(b.N)
}
// String implements flag.Value interface
func (b *Bytes) String() string {
return b.valueString
}
// Set implements flag.Value interface
func (b *Bytes) Set(value string) error {
value = normalizeBytesString(value)
switch {
case strings.HasSuffix(value, "KB"):
f, err := strconv.ParseFloat(value[:len(value)-2], 64)
if err != nil {
return err
}
b.N = int64(f * 1000)
b.valueString = value
return nil
case strings.HasSuffix(value, "MB"):
f, err := strconv.ParseFloat(value[:len(value)-2], 64)
if err != nil {
return err
}
b.N = int64(f * 1000 * 1000)
b.valueString = value
return nil
case strings.HasSuffix(value, "GB"):
f, err := strconv.ParseFloat(value[:len(value)-2], 64)
if err != nil {
return err
}
b.N = int64(f * 1000 * 1000 * 1000)
b.valueString = value
return nil
case strings.HasSuffix(value, "TB"):
f, err := strconv.ParseFloat(value[:len(value)-2], 64)
if err != nil {
return err
}
b.N = int64(f * 1000 * 1000 * 1000 * 1000)
b.valueString = value
return nil
case strings.HasSuffix(value, "KiB"):
f, err := strconv.ParseFloat(value[:len(value)-3], 64)
if err != nil {
return err
}
b.N = int64(f * 1024)
b.valueString = value
return nil
case strings.HasSuffix(value, "MiB"):
f, err := strconv.ParseFloat(value[:len(value)-3], 64)
if err != nil {
return err
}
b.N = int64(f * 1024 * 1024)
b.valueString = value
return nil
case strings.HasSuffix(value, "GiB"):
f, err := strconv.ParseFloat(value[:len(value)-3], 64)
if err != nil {
return err
}
b.N = int64(f * 1024 * 1024 * 1024)
b.valueString = value
return nil
case strings.HasSuffix(value, "TiB"):
f, err := strconv.ParseFloat(value[:len(value)-3], 64)
if err != nil {
return err
}
b.N = int64(f * 1024 * 1024 * 1024 * 1024)
b.valueString = value
return nil
default:
f, err := strconv.ParseFloat(value, 64)
if err != nil {
return err
}
b.N = int64(f)
b.valueString = value
return nil
}
}
func normalizeBytesString(s string) string {
s = strings.ToUpper(s)
return strings.ReplaceAll(s, "I", "i")
}