urfave-cli/internal/argh/parser_config.go
Dan Buch 06c70ea8eb
Gain some internal/argh
like a coral eats its neighbor
2022-11-09 20:46:07 -05:00

215 lines
3.6 KiB
Go

package argh
import "sync"
const (
OneOrMoreValue NValue = -2
ZeroOrMoreValue NValue = -1
ZeroValue NValue = 0
)
var (
zeroValuePtr = func() *NValue {
v := ZeroValue
return &v
}()
)
type NValue int
func (nv NValue) Required() bool {
if nv == OneOrMoreValue {
return true
}
return int(nv) >= 1
}
func (nv NValue) Contains(i int) bool {
tracef("NValue.Contains(%v)", i)
if i < int(ZeroValue) {
return false
}
if nv == OneOrMoreValue || nv == ZeroOrMoreValue {
return true
}
return int(nv) > i
}
type ParserConfig struct {
Prog *CommandConfig
ScannerConfig *ScannerConfig
}
type ParserOption func(*ParserConfig)
func NewParserConfig(opts ...ParserOption) *ParserConfig {
pCfg := &ParserConfig{}
for _, opt := range opts {
if opt != nil {
opt(pCfg)
}
}
if pCfg.Prog == nil {
pCfg.Prog = &CommandConfig{}
pCfg.Prog.init()
}
if pCfg.ScannerConfig == nil {
pCfg.ScannerConfig = POSIXyScannerConfig
}
return pCfg
}
type CommandConfig struct {
NValue NValue
ValueNames []string
Flags *Flags
Commands *Commands
On func(CommandFlag)
}
func (cCfg *CommandConfig) init() {
if cCfg.ValueNames == nil {
cCfg.ValueNames = []string{}
}
if cCfg.Flags == nil {
cCfg.Flags = &Flags{}
}
if cCfg.Commands == nil {
cCfg.Commands = &Commands{}
}
}
func (cCfg *CommandConfig) GetCommandConfig(name string) (CommandConfig, bool) {
tracef("CommandConfig.GetCommandConfig(%q)", name)
if cCfg.Commands == nil {
cCfg.Commands = &Commands{Map: map[string]CommandConfig{}}
}
return cCfg.Commands.Get(name)
}
func (cCfg *CommandConfig) GetFlagConfig(name string) (FlagConfig, bool) {
tracef("CommandConfig.GetFlagConfig(%q)", name)
if cCfg.Flags == nil {
cCfg.Flags = &Flags{Map: map[string]FlagConfig{}}
}
return cCfg.Flags.Get(name)
}
func (cCfg *CommandConfig) SetFlagConfig(name string, flCfg FlagConfig) {
tracef("CommandConfig.SetFlagConfig(%q, ...)", name)
if cCfg.Flags == nil {
cCfg.Flags = &Flags{Map: map[string]FlagConfig{}}
}
cCfg.Flags.Set(name, flCfg)
}
func (cCfg *CommandConfig) SetDefaultFlagConfig(name string, flCfg FlagConfig) {
tracef("CommandConfig.SetDefaultFlagConfig(%q, ...)", name)
if cCfg.Flags == nil {
cCfg.Flags = &Flags{Map: map[string]FlagConfig{}}
}
cCfg.Flags.SetDefault(name, flCfg)
}
type FlagConfig struct {
NValue NValue
Persist bool
ValueNames []string
On func(CommandFlag)
}
type Flags struct {
Parent *Flags
Map map[string]FlagConfig
Automatic bool
m sync.Mutex
}
func (fl *Flags) Get(name string) (FlagConfig, bool) {
tracef("Flags.Get(%q)", name)
if fl.Map == nil {
fl.Map = map[string]FlagConfig{}
}
flCfg, ok := fl.Map[name]
if !ok {
if fl.Automatic {
return FlagConfig{}, true
}
if fl.Parent != nil {
flCfg, ok = fl.Parent.Get(name)
return flCfg, ok && flCfg.Persist
}
}
return flCfg, ok
}
func (fl *Flags) Set(name string, flCfg FlagConfig) {
tracef("Flags.Set(%q, ...)", name)
fl.m.Lock()
defer fl.m.Unlock()
if fl.Map == nil {
fl.Map = map[string]FlagConfig{}
}
fl.Map[name] = flCfg
}
func (fl *Flags) SetDefault(name string, flCfg FlagConfig) {
tracef("Flags.SetDefault(%q, ...)", name)
fl.m.Lock()
defer fl.m.Unlock()
if fl.Map == nil {
fl.Map = map[string]FlagConfig{}
}
if _, ok := fl.Map[name]; !ok {
fl.Map[name] = flCfg
}
}
type Commands struct {
Map map[string]CommandConfig
}
func (cmd *Commands) Get(name string) (CommandConfig, bool) {
tracef("Commands.Get(%q)", name)
if cmd.Map == nil {
cmd.Map = map[string]CommandConfig{}
}
cmdCfg, ok := cmd.Map[name]
return cmdCfg, ok
}