Created
January 7, 2022 04:45
-
-
Save punmechanic/8a51a7bbb6b6300dde6dc9d915181390 to your computer and use it in GitHub Desktop.
crimes were committed to implement a small version of binding flags to an arbitrary struct
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package bind_flags | |
import ( | |
"reflect" | |
"github.com/spf13/pflag" | |
) | |
type Target struct { | |
Foo string `flag:"flag-name"` | |
} | |
// BindFlags binds the flags in the set to the given destination struct. | |
// | |
// dst MUST be a struct containing fields decorated with the flag tag. | |
// This is a close copy of what Cobra does with Viper, but without an entirely new library. | |
func BindFlags(dst interface{}, set *pflag.FlagSet) error { | |
// No need to do anything if we have no flags | |
if !set.HasFlags() { | |
return nil | |
} | |
// As this is not intended to be re-usable, we are not going to perform much validation here | |
// If you encounter cryptic errors at runtime, consult tests for usage | |
t := reflect.TypeOf(dst) | |
v := reflect.ValueOf(dst) | |
if t.Kind() == reflect.Ptr { | |
t = t.Elem() | |
v = v.Elem() | |
} | |
if t.Kind() != reflect.Struct { | |
panic("dst must be a pointer to a struct") | |
} | |
for i := 0; i < t.NumField(); i++ { | |
field := t.Field(i) | |
// We use v so that we can assign. We need to use t to get the struct tag information. | |
v2 := v.Field(i) | |
name, ok := field.Tag.Lookup("flag") | |
if !ok || !v2.CanSet() { | |
continue | |
} | |
// We only support a limited number of types, because we don't need to support everything | |
switch field.Type.Kind() { | |
case reflect.String: | |
a, err := set.GetString(name) | |
if err != nil { | |
return err | |
} | |
v2.SetString(a) | |
case reflect.Uint: | |
a, err := set.GetUint(name) | |
if err != nil { | |
return err | |
} | |
v2.SetUint(uint64(a)) | |
} | |
} | |
return nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment