2020-08-16 14:05:52 +00:00
|
|
|
package flagutil
|
|
|
|
|
|
|
|
import (
|
|
|
|
"flag"
|
|
|
|
"fmt"
|
2022-12-15 03:26:24 +00:00
|
|
|
"math"
|
2020-08-16 14:05:52 +00:00
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
// NewBytes returns new `bytes` flag with the given name, defaultValue and description.
|
2022-12-15 03:26:24 +00:00
|
|
|
func NewBytes(name string, defaultValue int64, description string) *Bytes {
|
2022-12-15 01:52:32 +00:00
|
|
|
description += "\nSupports the following optional suffixes for `size` values: KB, MB, GB, TB, KiB, MiB, GiB, TiB"
|
2020-08-16 14:05:52 +00:00
|
|
|
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.
|
|
|
|
//
|
2022-12-15 01:52:32 +00:00
|
|
|
// It supports the following optional suffixes for values: KB, MB, GB, TB, KiB, MiB, GiB, TiB.
|
2020-08-16 14:05:52 +00:00
|
|
|
type Bytes struct {
|
|
|
|
// N contains parsed value for the given flag.
|
2022-12-15 03:26:24 +00:00
|
|
|
N int64
|
2020-08-16 14:05:52 +00:00
|
|
|
|
|
|
|
valueString string
|
|
|
|
}
|
|
|
|
|
2022-12-15 03:26:24 +00:00
|
|
|
// 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)
|
|
|
|
}
|
|
|
|
|
2020-08-16 14:05:52 +00:00
|
|
|
// 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
|
|
|
|
}
|
2022-12-15 03:26:24 +00:00
|
|
|
b.N = int64(f * 1000)
|
2020-08-16 14:05:52 +00:00
|
|
|
b.valueString = value
|
|
|
|
return nil
|
|
|
|
case strings.HasSuffix(value, "MB"):
|
|
|
|
f, err := strconv.ParseFloat(value[:len(value)-2], 64)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-12-15 03:26:24 +00:00
|
|
|
b.N = int64(f * 1000 * 1000)
|
2020-08-16 14:05:52 +00:00
|
|
|
b.valueString = value
|
|
|
|
return nil
|
|
|
|
case strings.HasSuffix(value, "GB"):
|
|
|
|
f, err := strconv.ParseFloat(value[:len(value)-2], 64)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-12-15 03:26:24 +00:00
|
|
|
b.N = int64(f * 1000 * 1000 * 1000)
|
2020-08-16 14:05:52 +00:00
|
|
|
b.valueString = value
|
|
|
|
return nil
|
2022-12-15 01:52:32 +00:00
|
|
|
case strings.HasSuffix(value, "TB"):
|
|
|
|
f, err := strconv.ParseFloat(value[:len(value)-2], 64)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-12-15 03:26:24 +00:00
|
|
|
b.N = int64(f * 1000 * 1000 * 1000 * 1000)
|
2022-12-15 01:52:32 +00:00
|
|
|
b.valueString = value
|
|
|
|
return nil
|
2020-08-16 14:05:52 +00:00
|
|
|
case strings.HasSuffix(value, "KiB"):
|
|
|
|
f, err := strconv.ParseFloat(value[:len(value)-3], 64)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-12-15 03:26:24 +00:00
|
|
|
b.N = int64(f * 1024)
|
2020-08-16 14:05:52 +00:00
|
|
|
b.valueString = value
|
|
|
|
return nil
|
|
|
|
case strings.HasSuffix(value, "MiB"):
|
|
|
|
f, err := strconv.ParseFloat(value[:len(value)-3], 64)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-12-15 03:26:24 +00:00
|
|
|
b.N = int64(f * 1024 * 1024)
|
2020-08-16 14:05:52 +00:00
|
|
|
b.valueString = value
|
|
|
|
return nil
|
|
|
|
case strings.HasSuffix(value, "GiB"):
|
|
|
|
f, err := strconv.ParseFloat(value[:len(value)-3], 64)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-12-15 03:26:24 +00:00
|
|
|
b.N = int64(f * 1024 * 1024 * 1024)
|
2020-08-16 14:05:52 +00:00
|
|
|
b.valueString = value
|
|
|
|
return nil
|
2022-12-15 01:52:32 +00:00
|
|
|
case strings.HasSuffix(value, "TiB"):
|
|
|
|
f, err := strconv.ParseFloat(value[:len(value)-3], 64)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-12-15 03:26:24 +00:00
|
|
|
b.N = int64(f * 1024 * 1024 * 1024 * 1024)
|
2022-12-15 01:52:32 +00:00
|
|
|
b.valueString = value
|
|
|
|
return nil
|
2020-08-16 14:05:52 +00:00
|
|
|
default:
|
|
|
|
f, err := strconv.ParseFloat(value, 64)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-12-15 03:26:24 +00:00
|
|
|
b.N = int64(f)
|
2020-08-16 14:05:52 +00:00
|
|
|
b.valueString = value
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func normalizeBytesString(s string) string {
|
|
|
|
s = strings.ToUpper(s)
|
|
|
|
return strings.ReplaceAll(s, "I", "i")
|
|
|
|
}
|