Much more thorough checking of enum values.
This commit is contained in:
+31
-6
@@ -135,13 +135,10 @@ func (c *Context) Empty() bool {
|
||||
func (c *Context) Validate() error {
|
||||
err := Visit(c.Model, func(node Visitable, next Next) error {
|
||||
if value, ok := node.(*Value); ok {
|
||||
if value.Enum != "" && !value.EnumMap()[fmt.Sprintf("%v", value.Target.Interface())] {
|
||||
enums := []string{}
|
||||
for enum := range value.EnumMap() {
|
||||
enums = append(enums, fmt.Sprintf("%q", enum))
|
||||
if value.Enum != "" {
|
||||
if err := checkEnum(value, value.Target); err != nil {
|
||||
return err
|
||||
}
|
||||
sort.Strings(enums)
|
||||
return fmt.Errorf("%s must be one of %s but got %q", value.ShortSummary(), strings.Join(enums, ","), value.Target.Interface())
|
||||
}
|
||||
}
|
||||
return next(nil)
|
||||
@@ -646,6 +643,34 @@ func checkMissingPositionals(positional int, values []*Value) error {
|
||||
return fmt.Errorf("missing positional arguments %s", strings.Join(missing, " "))
|
||||
}
|
||||
|
||||
func checkEnum(value *Value, target reflect.Value) error {
|
||||
switch target.Kind() {
|
||||
case reflect.Slice, reflect.Array:
|
||||
for i := 0; i < target.Len(); i++ {
|
||||
if err := checkEnum(value, target.Index(i)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case reflect.Map, reflect.Struct:
|
||||
return errors.Errorf("enum can only be applied to a slice or value")
|
||||
|
||||
default:
|
||||
enumMap := value.EnumMap()
|
||||
v := fmt.Sprintf("%v", target)
|
||||
if enumMap[v] {
|
||||
return nil
|
||||
}
|
||||
enums := []string{}
|
||||
for enum := range enumMap {
|
||||
enums = append(enums, fmt.Sprintf("%q", enum))
|
||||
}
|
||||
sort.Strings(enums)
|
||||
return fmt.Errorf("%s must be one of %s but got %q", value.ShortSummary(), strings.Join(enums, ","), target.Interface())
|
||||
}
|
||||
}
|
||||
|
||||
func checkXorDuplicates(paths []*Path) error {
|
||||
for _, path := range paths {
|
||||
seen := map[string]*Flag{}
|
||||
|
||||
Reference in New Issue
Block a user