feat(autocli): add map support (#15770)
This commit is contained in:
parent
f358214b43
commit
62f0c6faf2
@ -2,13 +2,15 @@ package flag
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
|
||||
cosmos_proto "github.com/cosmos/cosmos-proto"
|
||||
"github.com/spf13/pflag"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
|
||||
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
|
||||
cosmos_proto "github.com/cosmos/cosmos-proto"
|
||||
|
||||
"cosmossdk.io/client/v2/internal/util"
|
||||
)
|
||||
|
||||
@ -60,8 +62,13 @@ func (b *Builder) addFieldFlag(ctx context.Context, flagSet *pflag.FlagSet, fiel
|
||||
|
||||
// use the built-in pflag StringP, Int32P, etc. functions
|
||||
var val HasValue
|
||||
|
||||
if field.IsList() {
|
||||
val = bindSimpleListFlag(flagSet, field.Kind(), name, shorthand, usage)
|
||||
} else if field.IsMap() {
|
||||
keyKind := field.MapKey().Kind()
|
||||
valKind := field.MapValue().Kind()
|
||||
val = bindSimpleMapFlag(flagSet, keyKind, valKind, name, shorthand, usage)
|
||||
} else {
|
||||
val = bindSimpleFlag(flagSet, field.Kind(), name, shorthand, usage)
|
||||
}
|
||||
@ -81,7 +88,65 @@ func (b *Builder) resolveFlagType(field protoreflect.FieldDescriptor) Type {
|
||||
if typ != nil {
|
||||
return compositeListType{simpleType: typ}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if field.IsMap() {
|
||||
keyKind := field.MapKey().Kind()
|
||||
valType := b.resolveFlagType(field.MapValue())
|
||||
if valType != nil {
|
||||
switch keyKind {
|
||||
case protoreflect.StringKind:
|
||||
ct := new(compositeMapType[string])
|
||||
ct.keyValueResolver = func(s string) (string, error) { return s, nil }
|
||||
ct.valueType = valType
|
||||
ct.keyType = "string"
|
||||
return ct
|
||||
case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
|
||||
ct := new(compositeMapType[int32])
|
||||
ct.keyValueResolver = func(s string) (int32, error) {
|
||||
i, err := strconv.ParseInt(s, 10, 32)
|
||||
return int32(i), err
|
||||
}
|
||||
ct.valueType = valType
|
||||
ct.keyType = "int32"
|
||||
return ct
|
||||
case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
|
||||
ct := new(compositeMapType[int64])
|
||||
ct.keyValueResolver = func(s string) (int64, error) {
|
||||
i, err := strconv.ParseInt(s, 10, 64)
|
||||
return i, err
|
||||
}
|
||||
ct.valueType = valType
|
||||
ct.keyType = "int64"
|
||||
return ct
|
||||
case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
|
||||
ct := new(compositeMapType[uint32])
|
||||
ct.keyValueResolver = func(s string) (uint32, error) {
|
||||
i, err := strconv.ParseUint(s, 10, 32)
|
||||
return uint32(i), err
|
||||
}
|
||||
ct.valueType = valType
|
||||
ct.keyType = "uint32"
|
||||
return ct
|
||||
case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
|
||||
ct := new(compositeMapType[uint64])
|
||||
ct.keyValueResolver = func(s string) (uint64, error) {
|
||||
i, err := strconv.ParseUint(s, 10, 64)
|
||||
return i, err
|
||||
}
|
||||
ct.valueType = valType
|
||||
ct.keyType = "uint64"
|
||||
return ct
|
||||
case protoreflect.BoolKind:
|
||||
ct := new(compositeMapType[bool])
|
||||
ct.keyValueResolver = strconv.ParseBool
|
||||
ct.valueType = valType
|
||||
ct.keyType = "bool"
|
||||
return ct
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -107,7 +172,6 @@ func (b *Builder) resolveFlagTypeBasic(field protoreflect.FieldDescriptor) Type
|
||||
if flagType, ok := b.messageFlagTypes[field.Message().FullName()]; ok {
|
||||
return flagType
|
||||
}
|
||||
|
||||
return jsonMessageFlagType{
|
||||
messageDesc: field.Message(),
|
||||
}
|
||||
|
||||
252
client/v2/autocli/flag/map.go
Normal file
252
client/v2/autocli/flag/map.go
Normal file
@ -0,0 +1,252 @@
|
||||
package flag
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/cockroachdb/errors"
|
||||
"github.com/spf13/pflag"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
)
|
||||
|
||||
func bindSimpleMapFlag(flagSet *pflag.FlagSet, keyKind, valueKind protoreflect.Kind, name, shorthand, usage string) HasValue {
|
||||
switch keyKind {
|
||||
case protoreflect.StringKind:
|
||||
switch valueKind {
|
||||
case protoreflect.StringKind:
|
||||
val := flagSet.StringToStringP(name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfString)
|
||||
case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
|
||||
val := StringToInt32P(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfInt32)
|
||||
case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
|
||||
val := flagSet.StringToInt64P(name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfInt64)
|
||||
case protoreflect.Uint32Kind:
|
||||
val := StringToUint32P(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfUint32)
|
||||
case protoreflect.Uint64Kind:
|
||||
val := StringToUint64P(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfUint64)
|
||||
case protoreflect.BoolKind:
|
||||
val := StringToBoolP(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfBool)
|
||||
}
|
||||
|
||||
case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
|
||||
switch valueKind {
|
||||
case protoreflect.StringKind:
|
||||
val := Int32ToStringP(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfString)
|
||||
case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
|
||||
val := Int32ToInt32P(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfInt32)
|
||||
case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
|
||||
val := Int32ToInt64P(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfInt64)
|
||||
case protoreflect.Uint32Kind:
|
||||
val := Int32ToUint32P(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfUint32)
|
||||
case protoreflect.Uint64Kind:
|
||||
val := Int32ToUint64P(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfUint64)
|
||||
case protoreflect.BoolKind:
|
||||
val := Int32ToBoolP(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfBool)
|
||||
}
|
||||
|
||||
case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
|
||||
switch valueKind {
|
||||
case protoreflect.StringKind:
|
||||
val := Int64ToStringP(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfString)
|
||||
case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
|
||||
val := Int64ToInt32P(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfInt32)
|
||||
case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
|
||||
val := Int64ToInt64P(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfInt64)
|
||||
case protoreflect.Uint32Kind:
|
||||
val := Int64ToUint32P(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfUint32)
|
||||
case protoreflect.Uint64Kind:
|
||||
val := Int64ToUint64P(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfUint64)
|
||||
case protoreflect.BoolKind:
|
||||
val := Int64ToBoolP(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfBool)
|
||||
}
|
||||
case protoreflect.Uint32Kind:
|
||||
switch valueKind {
|
||||
case protoreflect.StringKind:
|
||||
val := Uint32ToStringP(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfString)
|
||||
case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
|
||||
val := Uint32ToInt32P(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfInt32)
|
||||
case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
|
||||
val := Uint32ToInt64P(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfInt64)
|
||||
case protoreflect.Uint32Kind:
|
||||
val := Uint32ToUint32P(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfUint32)
|
||||
case protoreflect.Uint64Kind:
|
||||
val := Uint32ToUint64P(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfUint64)
|
||||
case protoreflect.BoolKind:
|
||||
val := Uint32ToBoolP(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfBool)
|
||||
}
|
||||
case protoreflect.Uint64Kind:
|
||||
switch valueKind {
|
||||
case protoreflect.StringKind:
|
||||
val := Uint64ToStringP(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfString)
|
||||
case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
|
||||
val := Uint64ToInt32P(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfInt32)
|
||||
case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
|
||||
val := Uint64ToInt64P(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfInt64)
|
||||
case protoreflect.Uint32Kind:
|
||||
val := Uint64ToUint32P(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfUint32)
|
||||
case protoreflect.Uint64Kind:
|
||||
val := Uint64ToUint64P(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfUint64)
|
||||
case protoreflect.BoolKind:
|
||||
val := Uint64ToBoolP(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfBool)
|
||||
}
|
||||
case protoreflect.BoolKind:
|
||||
switch valueKind {
|
||||
case protoreflect.StringKind:
|
||||
val := BoolToStringP(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfString)
|
||||
case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
|
||||
val := BoolToInt32P(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfInt32)
|
||||
case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
|
||||
val := BoolToInt64P(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfInt64)
|
||||
case protoreflect.Uint32Kind:
|
||||
val := BoolToUint32P(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfUint32)
|
||||
case protoreflect.Uint64Kind:
|
||||
val := BoolToUint64P(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfUint64)
|
||||
case protoreflect.BoolKind:
|
||||
val := BoolToBoolP(flagSet, name, shorthand, nil, usage)
|
||||
return newMapValue(val, protoreflect.ValueOfBool)
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type mapValue[K comparable, V any] struct {
|
||||
value *map[K]V
|
||||
toProtoreflectValue func(V) protoreflect.Value
|
||||
}
|
||||
|
||||
func newMapValue[K comparable, V any](mapV *map[K]V, toProtoreflectValue func(V) protoreflect.Value) mapValue[K, V] {
|
||||
return mapValue[K, V]{value: mapV, toProtoreflectValue: toProtoreflectValue}
|
||||
}
|
||||
|
||||
func (v mapValue[K, V]) Get(mutable protoreflect.Value) (protoreflect.Value, error) {
|
||||
protoMap := mutable.Map()
|
||||
for k, val := range *v.value {
|
||||
protoMap.Set(protoreflect.MapKey(protoreflect.ValueOf(k)), v.toProtoreflectValue(val))
|
||||
}
|
||||
return mutable, nil
|
||||
}
|
||||
|
||||
// keyValueResolver is a function that converts a string to a key that is primitive Type T
|
||||
type keyValueResolver[T comparable] func(string) (T, error)
|
||||
|
||||
// compositeMapType is a map type that is composed of a key and value type that are both primitive types
|
||||
type compositeMapType[T comparable] struct {
|
||||
keyValueResolver keyValueResolver[T]
|
||||
keyType string
|
||||
valueType Type
|
||||
}
|
||||
|
||||
// compositeMapValue is a map value that is composed of a key and value type that are both primitive types
|
||||
type compositeMapValue[T comparable] struct {
|
||||
keyValueResolver keyValueResolver[T]
|
||||
keyType string
|
||||
valueType Type
|
||||
values map[T]protoreflect.Value
|
||||
ctx context.Context
|
||||
opts *Builder
|
||||
}
|
||||
|
||||
func (m compositeMapType[T]) DefaultValue() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m compositeMapType[T]) NewValue(ctx context.Context, opts *Builder) Value {
|
||||
return &compositeMapValue[T]{
|
||||
keyValueResolver: m.keyValueResolver,
|
||||
valueType: m.valueType,
|
||||
keyType: m.keyType,
|
||||
ctx: ctx,
|
||||
opts: opts,
|
||||
values: nil,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *compositeMapValue[T]) Set(s string) error {
|
||||
comaArgs := strings.Split(s, ",")
|
||||
for _, arg := range comaArgs {
|
||||
parts := strings.SplitN(arg, "=", 2)
|
||||
if len(parts) != 2 {
|
||||
return errors.New("invalid format, expected key=value")
|
||||
}
|
||||
key, val := parts[0], parts[1]
|
||||
|
||||
keyValue, err := m.keyValueResolver(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
simpleVal := m.valueType.NewValue(m.ctx, m.opts)
|
||||
err = simpleVal.Set(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
protoValue, err := simpleVal.Get(protoreflect.Value{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if m.values == nil {
|
||||
m.values = make(map[T]protoreflect.Value)
|
||||
}
|
||||
|
||||
m.values[keyValue] = protoValue
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *compositeMapValue[T]) Get(mutable protoreflect.Value) (protoreflect.Value, error) {
|
||||
protoMap := mutable.Map()
|
||||
for key, value := range m.values {
|
||||
keyVal := protoreflect.ValueOf(key)
|
||||
protoMap.Set(keyVal.MapKey(), value)
|
||||
}
|
||||
return protoreflect.ValueOfMap(protoMap), nil
|
||||
}
|
||||
|
||||
func (m *compositeMapValue[T]) String() string {
|
||||
if m.values == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%+v", m.values)
|
||||
}
|
||||
|
||||
func (m *compositeMapValue[T]) Type() string {
|
||||
return fmt.Sprintf("map[%s]%s", m.keyType, m.valueType.NewValue(m.ctx, m.opts).Type())
|
||||
}
|
||||
138
client/v2/autocli/flag/map_bool_to_value.go
Normal file
138
client/v2/autocli/flag/map_bool_to_value.go
Normal file
@ -0,0 +1,138 @@
|
||||
package flag
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
func newBoolToString[K bool, V string](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newBoolStringMap := newGenericMapValue(val, p)
|
||||
newBoolStringMap.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "boolToString",
|
||||
keyParser: func(s string) (K, error) {
|
||||
value, err := strconv.ParseBool(s)
|
||||
return K(value), err
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
return V(s), nil
|
||||
},
|
||||
}
|
||||
return newBoolStringMap
|
||||
}
|
||||
|
||||
func BoolToStringP(flagSet *pflag.FlagSet, name, shorthand string, value map[bool]string, usage string) *map[bool]string {
|
||||
p := make(map[bool]string)
|
||||
flagSet.VarP(newBoolToString(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
func newBoolToInt32[K bool, V int32](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newBoolInt32Map := newGenericMapValue(val, p)
|
||||
newBoolInt32Map.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "boolToInt32",
|
||||
keyParser: func(s string) (K, error) {
|
||||
value, err := strconv.ParseBool(s)
|
||||
return K(value), err
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
value, err := strconv.ParseInt(s, 10, 32)
|
||||
return V(value), err
|
||||
},
|
||||
}
|
||||
return newBoolInt32Map
|
||||
}
|
||||
|
||||
func BoolToInt32P(flagSet *pflag.FlagSet, name, shorthand string, value map[bool]int32, usage string) *map[bool]int32 {
|
||||
p := make(map[bool]int32)
|
||||
flagSet.VarP(newBoolToInt32(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
func newBoolToInt64[K bool, V int64](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newBoolInt64Map := newGenericMapValue(val, p)
|
||||
newBoolInt64Map.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "boolToInt64",
|
||||
keyParser: func(s string) (K, error) {
|
||||
value, err := strconv.ParseBool(s)
|
||||
return K(value), err
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
value, err := strconv.ParseInt(s, 10, 64)
|
||||
return V(value), err
|
||||
},
|
||||
}
|
||||
return newBoolInt64Map
|
||||
}
|
||||
|
||||
func BoolToInt64P(flagSet *pflag.FlagSet, name, shorthand string, value map[bool]int64, usage string) *map[bool]int64 {
|
||||
p := make(map[bool]int64)
|
||||
flagSet.VarP(newBoolToInt64(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
func newBoolToUint32[K bool, V uint32](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newBoolUint32Map := newGenericMapValue(val, p)
|
||||
newBoolUint32Map.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "boolToUint32",
|
||||
keyParser: func(s string) (K, error) {
|
||||
value, err := strconv.ParseBool(s)
|
||||
return K(value), err
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
value, err := strconv.ParseUint(s, 10, 32)
|
||||
return V(value), err
|
||||
},
|
||||
}
|
||||
return newBoolUint32Map
|
||||
}
|
||||
|
||||
func BoolToUint32P(flagSet *pflag.FlagSet, name, shorthand string, value map[bool]uint32, usage string) *map[bool]uint32 {
|
||||
p := make(map[bool]uint32)
|
||||
flagSet.VarP(newBoolToUint32(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
func newBoolToUint64[K bool, V uint64](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newBoolUint64Map := newGenericMapValue(val, p)
|
||||
newBoolUint64Map.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "boolToUint64",
|
||||
keyParser: func(s string) (K, error) {
|
||||
value, err := strconv.ParseBool(s)
|
||||
return K(value), err
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
value, err := strconv.ParseUint(s, 10, 64)
|
||||
return V(value), err
|
||||
},
|
||||
}
|
||||
return newBoolUint64Map
|
||||
}
|
||||
|
||||
func BoolToUint64P(flagSet *pflag.FlagSet, name, shorthand string, value map[bool]uint64, usage string) *map[bool]uint64 {
|
||||
p := make(map[bool]uint64)
|
||||
flagSet.VarP(newBoolToUint64(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
func newBoolToBool[K, V bool](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newBoolBoolMap := newGenericMapValue(val, p)
|
||||
newBoolBoolMap.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "boolToBool",
|
||||
keyParser: func(s string) (K, error) {
|
||||
value, err := strconv.ParseBool(s)
|
||||
return K(value), err
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
value, err := strconv.ParseBool(s)
|
||||
return V(value), err
|
||||
},
|
||||
}
|
||||
return newBoolBoolMap
|
||||
}
|
||||
|
||||
func BoolToBoolP(flagSet *pflag.FlagSet, name, shorthand string, value map[bool]bool, usage string) *map[bool]bool {
|
||||
p := make(map[bool]bool)
|
||||
flagSet.VarP(newBoolToBool(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
159
client/v2/autocli/flag/map_int32_to_value.go
Normal file
159
client/v2/autocli/flag/map_int32_to_value.go
Normal file
@ -0,0 +1,159 @@
|
||||
package flag
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
func newInt32ToString[K int32, V string](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newInt32StringMap := newGenericMapValue(val, p)
|
||||
newInt32StringMap.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "int32ToString",
|
||||
keyParser: func(s string) (K, error) {
|
||||
value, err := strconv.ParseInt(s, 10, 32)
|
||||
return K(value), err
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
return V(s), nil
|
||||
},
|
||||
}
|
||||
return newInt32StringMap
|
||||
}
|
||||
|
||||
func Int32ToStringP(flagSet *pflag.FlagSet, name, shorthand string, value map[int32]string, usage string) *map[int32]string {
|
||||
p := make(map[int32]string)
|
||||
flagSet.VarP(newInt32ToString(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
func newInt32ToInt32[K, V int32](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newInt32Int32Map := newGenericMapValue(val, p)
|
||||
newInt32Int32Map.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "int32ToInt32",
|
||||
keyParser: func(s string) (K, error) {
|
||||
value, err := strconv.ParseInt(s, 10, 32)
|
||||
return K(value), err
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
value, err := strconv.ParseInt(s, 10, 32)
|
||||
return V(value), err
|
||||
},
|
||||
}
|
||||
return newInt32Int32Map
|
||||
}
|
||||
|
||||
func Int32ToInt32P(flagSet *pflag.FlagSet, name, shorthand string, value map[int32]int32, usage string) *map[int32]int32 {
|
||||
p := make(map[int32]int32)
|
||||
flagSet.VarP(newInt32ToInt32(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
func newInt32ToInt64[K int32, V int64](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newInt32Int64Map := newGenericMapValue(val, p)
|
||||
newInt32Int64Map.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "int32ToInt64",
|
||||
keyParser: func(s string) (K, error) {
|
||||
value, err := strconv.ParseInt(s, 10, 32)
|
||||
return K(value), err
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
value, err := strconv.ParseInt(s, 10, 64)
|
||||
return V(value), err
|
||||
},
|
||||
}
|
||||
return newInt32Int64Map
|
||||
}
|
||||
|
||||
func Int32ToInt64P(flagSet *pflag.FlagSet, name, shorthand string, value map[int32]int64, usage string) *map[int32]int64 {
|
||||
p := make(map[int32]int64)
|
||||
flagSet.VarP(newInt32ToInt64(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
func newInt32ToUint32[K int32, V uint32](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newInt32Uint32Map := newGenericMapValue(val, p)
|
||||
newInt32Uint32Map.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "int32ToUint32",
|
||||
keyParser: func(s string) (K, error) {
|
||||
value, err := strconv.ParseInt(s, 10, 32)
|
||||
return K(value), err
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
value, err := strconv.ParseUint(s, 10, 32)
|
||||
return V(value), err
|
||||
},
|
||||
}
|
||||
return newInt32Uint32Map
|
||||
}
|
||||
|
||||
func Int32ToUint32P(flagSet *pflag.FlagSet, name, shorthand string, value map[int32]uint32, usage string) *map[int32]uint32 {
|
||||
p := make(map[int32]uint32)
|
||||
flagSet.VarP(newInt32ToUint32(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
func newInt32ToUint64[K int32, V uint64](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newInt32Uint64Map := newGenericMapValue(val, p)
|
||||
newInt32Uint64Map.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "int32ToUint64",
|
||||
keyParser: func(s string) (K, error) {
|
||||
value, err := strconv.ParseInt(s, 10, 32)
|
||||
return K(value), err
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
value, err := strconv.ParseUint(s, 10, 64)
|
||||
return V(value), err
|
||||
},
|
||||
}
|
||||
return newInt32Uint64Map
|
||||
}
|
||||
|
||||
func Int32ToUint64P(flagSet *pflag.FlagSet, name, shorthand string, value map[int32]uint64, usage string) *map[int32]uint64 {
|
||||
p := make(map[int32]uint64)
|
||||
flagSet.VarP(newInt32ToUint64(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
func newInt32ToBool[K int32, V bool](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newInt32BoolMap := newGenericMapValue(val, p)
|
||||
newInt32BoolMap.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "int32ToBool",
|
||||
keyParser: func(s string) (K, error) {
|
||||
value, err := strconv.ParseInt(s, 10, 32)
|
||||
return K(value), err
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
value, err := strconv.ParseBool(s)
|
||||
return V(value), err
|
||||
},
|
||||
}
|
||||
return newInt32BoolMap
|
||||
}
|
||||
|
||||
func Int32ToBoolP(flagSet *pflag.FlagSet, name, shorthand string, value map[int32]bool, usage string) *map[int32]bool {
|
||||
p := make(map[int32]bool)
|
||||
flagSet.VarP(newInt32ToBool(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
func newStringToBool[K string, V bool](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newStringBoolMap := newGenericMapValue(val, p)
|
||||
newStringBoolMap.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "stringToBool",
|
||||
keyParser: func(s string) (K, error) {
|
||||
return K(s), nil
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
value, err := strconv.ParseBool(s)
|
||||
return V(value), err
|
||||
},
|
||||
}
|
||||
return newStringBoolMap
|
||||
}
|
||||
|
||||
func StringToBoolP(flagSet *pflag.FlagSet, name, shorthand string, value map[string]bool, usage string) *map[string]bool {
|
||||
p := make(map[string]bool)
|
||||
flagSet.VarP(newStringToBool(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
180
client/v2/autocli/flag/map_int64_to_value.go
Normal file
180
client/v2/autocli/flag/map_int64_to_value.go
Normal file
@ -0,0 +1,180 @@
|
||||
package flag
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
func newInt64ToString[K int64, V string](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newInt64StringMap := newGenericMapValue(val, p)
|
||||
newInt64StringMap.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "int64ToString",
|
||||
keyParser: func(s string) (K, error) {
|
||||
value, err := strconv.ParseInt(s, 10, 64)
|
||||
return K(value), err
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
return V(s), nil
|
||||
},
|
||||
}
|
||||
return newInt64StringMap
|
||||
}
|
||||
|
||||
func Int64ToStringP(flagSet *pflag.FlagSet, name, shorthand string, value map[int64]string, usage string) *map[int64]string {
|
||||
p := make(map[int64]string)
|
||||
flagSet.VarP(newInt64ToString(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
func newInt64ToInt32[K int64, V int32](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newInt64Int32Map := newGenericMapValue(val, p)
|
||||
newInt64Int32Map.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "int64ToInt32",
|
||||
keyParser: func(s string) (K, error) {
|
||||
value, err := strconv.ParseInt(s, 10, 64)
|
||||
return K(value), err
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
value, err := strconv.ParseInt(s, 10, 32)
|
||||
return V(value), err
|
||||
},
|
||||
}
|
||||
return newInt64Int32Map
|
||||
}
|
||||
|
||||
func Int64ToInt32P(flagSet *pflag.FlagSet, name, shorthand string, value map[int64]int32, usage string) *map[int64]int32 {
|
||||
p := make(map[int64]int32)
|
||||
flagSet.VarP(newInt64ToInt32(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
func newInt64ToInt64[K, V int64](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newInt64Int64Map := newGenericMapValue(val, p)
|
||||
newInt64Int64Map.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "int64ToInt64",
|
||||
keyParser: func(s string) (K, error) {
|
||||
value, err := strconv.ParseInt(s, 10, 64)
|
||||
return K(value), err
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
value, err := strconv.ParseInt(s, 10, 64)
|
||||
return V(value), err
|
||||
},
|
||||
}
|
||||
return newInt64Int64Map
|
||||
}
|
||||
|
||||
func Int64ToInt64P(flagSet *pflag.FlagSet, name, shorthand string, value map[int64]int64, usage string) *map[int64]int64 {
|
||||
p := make(map[int64]int64)
|
||||
flagSet.VarP(newInt64ToInt64(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
func newInt64ToUint32[K int64, V uint32](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newInt64Uint32Map := newGenericMapValue(val, p)
|
||||
newInt64Uint32Map.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "int64ToUint32",
|
||||
keyParser: func(s string) (K, error) {
|
||||
value, err := strconv.ParseInt(s, 10, 64)
|
||||
return K(value), err
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
value, err := strconv.ParseUint(s, 10, 32)
|
||||
return V(value), err
|
||||
},
|
||||
}
|
||||
return newInt64Uint32Map
|
||||
}
|
||||
|
||||
func Int64ToUint32P(flagSet *pflag.FlagSet, name, shorthand string, value map[int64]uint32, usage string) *map[int64]uint32 {
|
||||
p := make(map[int64]uint32)
|
||||
flagSet.VarP(newInt64ToUint32(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
func newInt64ToUint64[K int64, V uint64](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newInt64Uint64Map := newGenericMapValue(val, p)
|
||||
newInt64Uint64Map.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "int64ToUint64",
|
||||
keyParser: func(s string) (K, error) {
|
||||
value, err := strconv.ParseInt(s, 10, 64)
|
||||
return K(value), err
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
value, err := strconv.ParseUint(s, 10, 64)
|
||||
return V(value), err
|
||||
},
|
||||
}
|
||||
return newInt64Uint64Map
|
||||
}
|
||||
|
||||
func Int64ToUint64P(flagSet *pflag.FlagSet, name, shorthand string, value map[int64]uint64, usage string) *map[int64]uint64 {
|
||||
p := make(map[int64]uint64)
|
||||
flagSet.VarP(newInt64ToUint64(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
func newInt64ToBool[K int64, V bool](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newInt64BoolMap := newGenericMapValue(val, p)
|
||||
newInt64BoolMap.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "int64ToBool",
|
||||
keyParser: func(s string) (K, error) {
|
||||
value, err := strconv.ParseInt(s, 10, 64)
|
||||
return K(value), err
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
value, err := strconv.ParseBool(s)
|
||||
return V(value), err
|
||||
},
|
||||
}
|
||||
return newInt64BoolMap
|
||||
}
|
||||
|
||||
func Int64ToBoolP(flagSet *pflag.FlagSet, name, shorthand string, value map[int64]bool, usage string) *map[int64]bool {
|
||||
p := make(map[int64]bool)
|
||||
flagSet.VarP(newInt64ToBool(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
func newStringToUint32[K string, V uint32](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newStringUintMap := newGenericMapValue(val, p)
|
||||
newStringUintMap.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "stringToUint32",
|
||||
keyParser: func(s string) (K, error) {
|
||||
return K(s), nil
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
value, err := strconv.ParseUint(s, 10, 32)
|
||||
return V(value), err
|
||||
},
|
||||
}
|
||||
return newStringUintMap
|
||||
}
|
||||
|
||||
func StringToUint32P(flagSet *pflag.FlagSet, name, shorthand string, value map[string]uint32, usage string) *map[string]uint32 {
|
||||
p := make(map[string]uint32)
|
||||
flagSet.VarP(newStringToUint32(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
func newStringToUint64[K string, V uint64](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newStringUint64Map := newGenericMapValue(val, p)
|
||||
newStringUint64Map.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "stringToUint64",
|
||||
keyParser: func(s string) (K, error) {
|
||||
return K(s), nil
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
value, err := strconv.ParseUint(s, 10, 64)
|
||||
return V(value), err
|
||||
},
|
||||
}
|
||||
return newStringUint64Map
|
||||
}
|
||||
|
||||
func StringToUint64P(flagSet *pflag.FlagSet, name, shorthand string, value map[string]uint64, usage string) *map[string]uint64 {
|
||||
p := make(map[string]uint64)
|
||||
flagSet.VarP(newStringToUint64(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
28
client/v2/autocli/flag/map_string_to_value.go
Normal file
28
client/v2/autocli/flag/map_string_to_value.go
Normal file
@ -0,0 +1,28 @@
|
||||
package flag
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
func newStringToInt32[K string, V int32](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newStringIntMap := newGenericMapValue(val, p)
|
||||
newStringIntMap.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "stringToInt32",
|
||||
keyParser: func(s string) (K, error) {
|
||||
return K(s), nil
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
value, err := strconv.ParseInt(s, 10, 32)
|
||||
return V(value), err
|
||||
},
|
||||
}
|
||||
return newStringIntMap
|
||||
}
|
||||
|
||||
func StringToInt32P(flagSet *pflag.FlagSet, name, shorthand string, value map[string]int32, usage string) *map[string]int32 {
|
||||
p := make(map[string]int32)
|
||||
flagSet.VarP(newStringToInt32(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
62
client/v2/autocli/flag/map_types.go
Normal file
62
client/v2/autocli/flag/map_types.go
Normal file
@ -0,0 +1,62 @@
|
||||
package flag
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/cockroachdb/errors"
|
||||
)
|
||||
|
||||
type genericMapValueOptions[K comparable, V any] struct {
|
||||
keyParser func(string) (K, error)
|
||||
valueParser func(string) (V, error)
|
||||
genericType string
|
||||
}
|
||||
|
||||
type genericMapValue[K comparable, V any] struct {
|
||||
value *map[K]V
|
||||
changed bool
|
||||
Options genericMapValueOptions[K, V]
|
||||
}
|
||||
|
||||
func newGenericMapValue[K comparable, V any](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
ssv := new(genericMapValue[K, V])
|
||||
ssv.value = p
|
||||
*ssv.value = val
|
||||
return ssv
|
||||
}
|
||||
|
||||
func (gm *genericMapValue[K, V]) Set(val string) error {
|
||||
ss := strings.Split(val, ",")
|
||||
out := make(map[K]V, len(ss))
|
||||
for _, pair := range ss {
|
||||
kv := strings.SplitN(pair, "=", 2)
|
||||
if len(kv) != 2 {
|
||||
return errors.Errorf("%s must be formatted as key=value", pair)
|
||||
}
|
||||
key, err := gm.Options.keyParser(kv[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
out[key], err = gm.Options.valueParser(kv[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if !gm.changed {
|
||||
*gm.value = out
|
||||
} else {
|
||||
for k, v := range out {
|
||||
(*gm.value)[k] = v
|
||||
}
|
||||
}
|
||||
gm.changed = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gm *genericMapValue[K, V]) Type() string {
|
||||
return gm.Options.genericType
|
||||
}
|
||||
|
||||
func (gm *genericMapValue[K, V]) String() string {
|
||||
return ""
|
||||
}
|
||||
138
client/v2/autocli/flag/map_uint32_to_value.go
Normal file
138
client/v2/autocli/flag/map_uint32_to_value.go
Normal file
@ -0,0 +1,138 @@
|
||||
package flag
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
func newUint32ToString[K uint32, V string](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newUint32StringMap := newGenericMapValue(val, p)
|
||||
newUint32StringMap.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "uint32ToString",
|
||||
keyParser: func(s string) (K, error) {
|
||||
value, err := strconv.ParseUint(s, 10, 32)
|
||||
return K(value), err
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
return V(s), nil
|
||||
},
|
||||
}
|
||||
return newUint32StringMap
|
||||
}
|
||||
|
||||
func Uint32ToStringP(flagSet *pflag.FlagSet, name, shorthand string, value map[uint32]string, usage string) *map[uint32]string {
|
||||
p := make(map[uint32]string)
|
||||
flagSet.VarP(newUint32ToString(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
func newUint32ToInt32[K uint32, V int32](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newUint32Int32Map := newGenericMapValue(val, p)
|
||||
newUint32Int32Map.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "uint32ToInt32",
|
||||
keyParser: func(s string) (K, error) {
|
||||
value, err := strconv.ParseUint(s, 10, 32)
|
||||
return K(value), err
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
value, err := strconv.ParseInt(s, 10, 32)
|
||||
return V(value), err
|
||||
},
|
||||
}
|
||||
return newUint32Int32Map
|
||||
}
|
||||
|
||||
func Uint32ToInt32P(flagSet *pflag.FlagSet, name, shorthand string, value map[uint32]int32, usage string) *map[uint32]int32 {
|
||||
p := make(map[uint32]int32)
|
||||
flagSet.VarP(newUint32ToInt32(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
func newUint32ToInt64[K uint32, V int64](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newUint32Int64Map := newGenericMapValue(val, p)
|
||||
newUint32Int64Map.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "uint32ToInt64",
|
||||
keyParser: func(s string) (K, error) {
|
||||
value, err := strconv.ParseUint(s, 10, 32)
|
||||
return K(value), err
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
value, err := strconv.ParseInt(s, 10, 64)
|
||||
return V(value), err
|
||||
},
|
||||
}
|
||||
return newUint32Int64Map
|
||||
}
|
||||
|
||||
func Uint32ToInt64P(flagSet *pflag.FlagSet, name, shorthand string, value map[uint32]int64, usage string) *map[uint32]int64 {
|
||||
p := make(map[uint32]int64)
|
||||
flagSet.VarP(newUint32ToInt64(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
func newUint32ToUint32[K, V uint32](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newUint32Uint32Map := newGenericMapValue(val, p)
|
||||
newUint32Uint32Map.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "uint32ToUint32",
|
||||
keyParser: func(s string) (K, error) {
|
||||
value, err := strconv.ParseUint(s, 10, 32)
|
||||
return K(value), err
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
value, err := strconv.ParseUint(s, 10, 32)
|
||||
return V(value), err
|
||||
},
|
||||
}
|
||||
return newUint32Uint32Map
|
||||
}
|
||||
|
||||
func Uint32ToUint32P(flagSet *pflag.FlagSet, name, shorthand string, value map[uint32]uint32, usage string) *map[uint32]uint32 {
|
||||
p := make(map[uint32]uint32)
|
||||
flagSet.VarP(newUint32ToUint32(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
func newUint32ToUint64[K uint32, V uint64](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newUint32Uint64Map := newGenericMapValue(val, p)
|
||||
newUint32Uint64Map.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "uint32ToUint64",
|
||||
keyParser: func(s string) (K, error) {
|
||||
value, err := strconv.ParseUint(s, 10, 32)
|
||||
return K(value), err
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
value, err := strconv.ParseUint(s, 10, 64)
|
||||
return V(value), err
|
||||
},
|
||||
}
|
||||
return newUint32Uint64Map
|
||||
}
|
||||
|
||||
func Uint32ToUint64P(flagSet *pflag.FlagSet, name, shorthand string, value map[uint32]uint64, usage string) *map[uint32]uint64 {
|
||||
p := make(map[uint32]uint64)
|
||||
flagSet.VarP(newUint32ToUint64(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
func newUint32ToBool[K uint32, V bool](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newUint32BoolMap := newGenericMapValue(val, p)
|
||||
newUint32BoolMap.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "uint32ToBool",
|
||||
keyParser: func(s string) (K, error) {
|
||||
value, err := strconv.ParseUint(s, 10, 32)
|
||||
return K(value), err
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
value, err := strconv.ParseBool(s)
|
||||
return V(value), err
|
||||
},
|
||||
}
|
||||
return newUint32BoolMap
|
||||
}
|
||||
|
||||
func Uint32ToBoolP(flagSet *pflag.FlagSet, name, shorthand string, value map[uint32]bool, usage string) *map[uint32]bool {
|
||||
p := make(map[uint32]bool)
|
||||
flagSet.VarP(newUint32ToBool(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
138
client/v2/autocli/flag/map_uint64_to_value.go
Normal file
138
client/v2/autocli/flag/map_uint64_to_value.go
Normal file
@ -0,0 +1,138 @@
|
||||
package flag
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
func newUint64ToString[K uint64, V string](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newUint64StringMap := newGenericMapValue(val, p)
|
||||
newUint64StringMap.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "uint64ToString",
|
||||
keyParser: func(s string) (K, error) {
|
||||
value, err := strconv.ParseUint(s, 10, 64)
|
||||
return K(value), err
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
return V(s), nil
|
||||
},
|
||||
}
|
||||
return newUint64StringMap
|
||||
}
|
||||
|
||||
func Uint64ToStringP(flagSet *pflag.FlagSet, name, shorthand string, value map[uint64]string, usage string) *map[uint64]string {
|
||||
p := make(map[uint64]string)
|
||||
flagSet.VarP(newUint64ToString(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
func newUint64ToInt32[K uint64, V int32](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newUint64Int32Map := newGenericMapValue(val, p)
|
||||
newUint64Int32Map.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "uint64ToInt32",
|
||||
keyParser: func(s string) (K, error) {
|
||||
value, err := strconv.ParseUint(s, 10, 64)
|
||||
return K(value), err
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
value, err := strconv.ParseInt(s, 10, 32)
|
||||
return V(value), err
|
||||
},
|
||||
}
|
||||
return newUint64Int32Map
|
||||
}
|
||||
|
||||
func Uint64ToInt32P(flagSet *pflag.FlagSet, name, shorthand string, value map[uint64]int32, usage string) *map[uint64]int32 {
|
||||
p := make(map[uint64]int32)
|
||||
flagSet.VarP(newUint64ToInt32(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
func newUint64ToInt64[K uint64, V int64](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newUint64Int64Map := newGenericMapValue(val, p)
|
||||
newUint64Int64Map.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "uint64ToInt64",
|
||||
keyParser: func(s string) (K, error) {
|
||||
value, err := strconv.ParseUint(s, 10, 64)
|
||||
return K(value), err
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
value, err := strconv.ParseInt(s, 10, 64)
|
||||
return V(value), err
|
||||
},
|
||||
}
|
||||
return newUint64Int64Map
|
||||
}
|
||||
|
||||
func Uint64ToInt64P(flagSet *pflag.FlagSet, name, shorthand string, value map[uint64]int64, usage string) *map[uint64]int64 {
|
||||
p := make(map[uint64]int64)
|
||||
flagSet.VarP(newUint64ToInt64(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
func newUint64ToUint32[K uint64, V uint32](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newUint64Uint32Map := newGenericMapValue(val, p)
|
||||
newUint64Uint32Map.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "uint64ToUint32",
|
||||
keyParser: func(s string) (K, error) {
|
||||
value, err := strconv.ParseUint(s, 10, 64)
|
||||
return K(value), err
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
value, err := strconv.ParseUint(s, 10, 32)
|
||||
return V(value), err
|
||||
},
|
||||
}
|
||||
return newUint64Uint32Map
|
||||
}
|
||||
|
||||
func Uint64ToUint32P(flagSet *pflag.FlagSet, name, shorthand string, value map[uint64]uint32, usage string) *map[uint64]uint32 {
|
||||
p := make(map[uint64]uint32)
|
||||
flagSet.VarP(newUint64ToUint32(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
func newUint64ToUint64[K, V uint64](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newUint64Uint64Map := newGenericMapValue(val, p)
|
||||
newUint64Uint64Map.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "uint64ToUint64",
|
||||
keyParser: func(s string) (K, error) {
|
||||
value, err := strconv.ParseUint(s, 10, 64)
|
||||
return K(value), err
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
value, err := strconv.ParseUint(s, 10, 64)
|
||||
return V(value), err
|
||||
},
|
||||
}
|
||||
return newUint64Uint64Map
|
||||
}
|
||||
|
||||
func Uint64ToUint64P(flagSet *pflag.FlagSet, name, shorthand string, value map[uint64]uint64, usage string) *map[uint64]uint64 {
|
||||
p := make(map[uint64]uint64)
|
||||
flagSet.VarP(newUint64ToUint64(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
func newUint64ToBool[K uint64, V bool](val map[K]V, p *map[K]V) *genericMapValue[K, V] {
|
||||
newUint64BoolMap := newGenericMapValue(val, p)
|
||||
newUint64BoolMap.Options = genericMapValueOptions[K, V]{
|
||||
genericType: "uint64ToBool",
|
||||
keyParser: func(s string) (K, error) {
|
||||
value, err := strconv.ParseUint(s, 10, 64)
|
||||
return K(value), err
|
||||
},
|
||||
valueParser: func(s string) (V, error) {
|
||||
value, err := strconv.ParseBool(s)
|
||||
return V(value), err
|
||||
},
|
||||
}
|
||||
return newUint64BoolMap
|
||||
}
|
||||
|
||||
func Uint64ToBoolP(flagSet *pflag.FlagSet, name, shorthand string, value map[uint64]bool, usage string) *map[uint64]bool {
|
||||
p := make(map[uint64]bool)
|
||||
flagSet.VarP(newUint64ToBool(value, &p), name, shorthand, usage)
|
||||
return &p
|
||||
}
|
||||
@ -82,6 +82,15 @@ var testCmdDesc = &autocliv1.ServiceCommandDescriptor{
|
||||
"bz": {
|
||||
Usage: "some bytes",
|
||||
},
|
||||
"map_string_string": {
|
||||
Usage: "some map of string to string",
|
||||
},
|
||||
"map_string_uint32": {
|
||||
Usage: "some map of string to int32",
|
||||
},
|
||||
"map_string_coin": {
|
||||
Usage: "some map of string to coin",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -121,6 +130,72 @@ func TestCoin(t *testing.T) {
|
||||
assert.DeepEqual(t, conn.lastRequest, conn.lastResponse.(*testpb.EchoResponse).Request, protocmp.Transform())
|
||||
}
|
||||
|
||||
func TestMap(t *testing.T) {
|
||||
conn := testExecCommon(t, buildModuleQueryCommand,
|
||||
"echo",
|
||||
"1",
|
||||
"abc",
|
||||
"1234foo",
|
||||
"4321bar",
|
||||
"--map-string-uint32", "bar=123",
|
||||
"--map-string-string", "val=foo",
|
||||
"--map-string-coin", "baz=100000foo",
|
||||
"--map-string-coin", "sec=100000bar",
|
||||
"--map-string-coin", "multi=100000bar,flag=100000foo",
|
||||
)
|
||||
assert.DeepEqual(t, conn.lastRequest, conn.lastResponse.(*testpb.EchoResponse).Request, protocmp.Transform())
|
||||
|
||||
conn = testExecCommon(t, buildModuleQueryCommand,
|
||||
"echo",
|
||||
"1",
|
||||
"abc",
|
||||
"1234foo",
|
||||
"4321bar",
|
||||
"--map-string-uint32", "bar=123",
|
||||
"--map-string-coin", "baz,100000foo",
|
||||
"--map-string-coin", "sec=100000bar",
|
||||
)
|
||||
assert.Equal(t, "Error: invalid argument \"baz,100000foo\" for \"--map-string-coin\" flag: invalid format, expected key=value\n", conn.errorOut.String())
|
||||
|
||||
conn = testExecCommon(t, buildModuleQueryCommand,
|
||||
"echo",
|
||||
"1",
|
||||
"abc",
|
||||
"1234foo",
|
||||
"4321bar",
|
||||
"--map-string-uint32", "bar=not-unint32",
|
||||
"--map-string-coin", "baz=100000foo",
|
||||
"--map-string-coin", "sec=100000bar",
|
||||
)
|
||||
assert.Equal(t, "Error: invalid argument \"bar=not-unint32\" for \"--map-string-uint32\" flag: strconv.ParseUint: parsing \"not-unint32\": invalid syntax\n", conn.errorOut.String())
|
||||
|
||||
conn = testExecCommon(t, buildModuleQueryCommand,
|
||||
"echo",
|
||||
"1",
|
||||
"abc",
|
||||
"1234foo",
|
||||
"4321bar",
|
||||
"--map-string-uint32", "bar=123.9",
|
||||
"--map-string-coin", "baz=100000foo",
|
||||
"--map-string-coin", "sec=100000bar",
|
||||
)
|
||||
assert.Equal(t, "Error: invalid argument \"bar=123.9\" for \"--map-string-uint32\" flag: strconv.ParseUint: parsing \"123.9\": invalid syntax\n", conn.errorOut.String())
|
||||
}
|
||||
|
||||
func TestMapError(t *testing.T) {
|
||||
conn := testExecCommon(t, buildModuleQueryCommand,
|
||||
"echo",
|
||||
"1",
|
||||
"abc",
|
||||
"1234foo",
|
||||
"4321bar",
|
||||
"--map-string-uint32", "bar=123",
|
||||
"--map-string-coin", "baz=100000foo",
|
||||
"--map-string-coin", "sec=100000bar",
|
||||
)
|
||||
assert.DeepEqual(t, conn.lastRequest, conn.lastResponse.(*testpb.EchoResponse).Request, protocmp.Transform())
|
||||
}
|
||||
|
||||
func TestEverything(t *testing.T) {
|
||||
conn := testExecCommon(t, buildModuleQueryCommand,
|
||||
"echo",
|
||||
@ -163,9 +238,6 @@ func TestEverything(t *testing.T) {
|
||||
"--uints", "1,2,3",
|
||||
"--uints", "4",
|
||||
)
|
||||
errOut := conn.errorOut.String()
|
||||
res := conn.out.String()
|
||||
fmt.Println(errOut, res)
|
||||
assert.DeepEqual(t, conn.lastRequest, conn.lastResponse.(*testpb.EchoResponse).Request, protocmp.Transform())
|
||||
}
|
||||
|
||||
|
||||
@ -21,6 +21,9 @@ Flags:
|
||||
--hidden-bool
|
||||
--i32 int32
|
||||
--i64 int
|
||||
--map-string-coin map[string]cosmos.base.v1beta1.Coin
|
||||
--map-string-string stringToString (default [])
|
||||
--map-string-uint32 stringToUint32
|
||||
--node string <host>:<port> to CometBFT RPC interface for this chain (default "tcp://localhost:26657")
|
||||
-o, --output string Output format (text|json) (default "text")
|
||||
--page-count-total
|
||||
|
||||
3
client/v2/autocli/testdata/help-echo.golden
vendored
3
client/v2/autocli/testdata/help-echo.golden
vendored
@ -27,6 +27,9 @@ Flags:
|
||||
-h, --help help for echo
|
||||
--i32 int32 some random int32
|
||||
--i64 int
|
||||
--map-string-coin map[string]cosmos.base.v1beta1.Coin some map of string to coin
|
||||
--map-string-string stringToString some map of string to string (default [])
|
||||
--map-string-uint32 stringToUint32 some map of string to int32
|
||||
--node string <host>:<port> to CometBFT RPC interface for this chain (default "tcp://localhost:26657")
|
||||
-o, --output string Output format (text|json) (default "text")
|
||||
--page-count-total
|
||||
|
||||
@ -43,6 +43,9 @@ message EchoRequest {
|
||||
string deprecated_field = 30;
|
||||
string shorthand_deprecated_field = 31;
|
||||
bool hidden_bool = 32;
|
||||
map<string, string> map_string_string = 33;
|
||||
map<string, uint32> map_string_uint32 = 34;
|
||||
map<string, cosmos.base.v1beta1.Coin> map_string_coin = 35;
|
||||
}
|
||||
|
||||
enum Enum {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user