Option types: bool int, int-array, string, string-array, string-map, file, dir
112 lines
2.7 KiB
Go
112 lines
2.7 KiB
Go
package cli
|
|
|
|
import (
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
const (
|
|
intArrayTypeName = "num-array"
|
|
)
|
|
|
|
type cliOptionIntArray struct {
|
|
cliOptionBase
|
|
defaultValue []int
|
|
targetVar *[]int
|
|
}
|
|
|
|
func (opt *cliOptionIntArray) init() {
|
|
if opt.targetVar != nil {
|
|
*opt.targetVar = opt.defaultValue
|
|
}
|
|
}
|
|
|
|
func (opt *cliOptionIntArray) getTargetVar() (any, string) {
|
|
var value []int
|
|
if opt.targetVar != nil {
|
|
value = *opt.targetVar
|
|
}
|
|
return value, intArrayTypeName
|
|
}
|
|
|
|
func (opt *cliOptionIntArray) requiresValue() bool {
|
|
return opt.targetVar != nil
|
|
}
|
|
|
|
func (opt *cliOptionIntArray) getDefaultValue() string {
|
|
def := make([]string, len(opt.defaultValue))
|
|
for i, v := range opt.defaultValue {
|
|
def[i] = strconv.Itoa(v)
|
|
}
|
|
return strings.Join(def, ",")
|
|
}
|
|
|
|
func (opt *cliOptionIntArray) getTemplate() string {
|
|
return opt.makeOptTemplate(true, "num")
|
|
}
|
|
|
|
func parseIntRange(value string) (min int, max int, err error) {
|
|
var dashPresent bool
|
|
var minStr, maxStr string
|
|
minStr, maxStr, dashPresent = strings.Cut(value, "-")
|
|
if dashPresent {
|
|
if min, err = strconv.Atoi(minStr); err == nil {
|
|
if max, err = strconv.Atoi(maxStr); err == nil {
|
|
if min > max {
|
|
err = errInvalidOptionValue("", value, "invalid range")
|
|
}
|
|
}
|
|
}
|
|
} else if min, err = strconv.Atoi(value); err == nil {
|
|
max = min
|
|
}
|
|
return
|
|
}
|
|
|
|
func (opt *cliOptionIntArray) parse(parser cliParser, argIndex int, valuePtr *string) (skipNextArg bool, err error) {
|
|
var optValue string
|
|
if optValue, skipNextArg, err = opt.fetchOptionValue(parser, argIndex, valuePtr); err == nil {
|
|
var boxedValue any
|
|
if boxedValue, err = opt.getSpecialValue(parser, optValue, opt.targetVar); err == nil {
|
|
if opt.targetVar != nil {
|
|
if boxedValue != nil {
|
|
if val, ok := boxedValue.([]int); ok {
|
|
*opt.targetVar = val
|
|
} else {
|
|
err = errInvalidOptionValue(opt.name, boxedValue, "array of int")
|
|
}
|
|
} else {
|
|
for value := range strings.SplitSeq(optValue, ",") {
|
|
var minRange, maxRange int
|
|
if minRange, maxRange, err = parseIntRange(value); err == nil {
|
|
for i := minRange; i <= maxRange; i++ {
|
|
*opt.targetVar = append(*opt.targetVar, i)
|
|
}
|
|
} else {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (cli *CliParser) AddIntArrayOpt(name, short string, targetVar *[]int, defaultValue []int, description string, aliases ...string) OptReference {
|
|
aliases = cli.checkAlreadyUsedNames(name, short, aliases)
|
|
opt := &cliOptionIntArray{
|
|
cliOptionBase: cliOptionBase{
|
|
name: name,
|
|
shortAlias: short,
|
|
aliases: aliases,
|
|
description: description,
|
|
isArray: true,
|
|
},
|
|
targetVar: targetVar,
|
|
defaultValue: defaultValue,
|
|
}
|
|
cli.options = append(cli.options, opt)
|
|
return opt
|
|
}
|