Hey Gophers! I'm trying to generate flags based on struct fields via reflection and I reached an issue with Type Assertion and pointers to struct value, I hope someone can point me in the right direction. This is to do some kind of Task manager library to make my life easier writing binaries.
Example: (note this is a short example without Kind() checks and without PkgPath check for only Exported fields)
type Test struct {
Name string `cmd:"Usage message"`
}
// This will be the tested Method for the command line
func (t Test) Hello() {
fmt.Println("Hello", t.Name)
}
func GenerateFlags(cmd interface{}) error {
cmdType := reflect.TypeOf(cmd)
// Validate Kind() is reflection.Struct and proceed
for i := 0; i < cmdType.NumField(); i++ {
field := cmdType.Field(i) // Get the StructField
// Validate field.PkgPath == "" so we know its an Exported field
cmdValue := reflect.ValueOf(cmd) // In case we need to use the reflection.Value
value := cmdValue.FieldByName(field.Name).Interface() // get the interface to work with
switch value.(type) {
// Switch cases for each of supported flags values
case string:
// Below the type assertion as we give the value of the flag is OK, my problem is trying to get a pointer of the valid type via reflection
flag.StringVar(/*HERE IS MY ISSUE*/,field.Name, value.(string) , field.Tag.Get("cmd"))
}
}
}
func main() {
GenerateFlags(Test{"World"}) // Default value for the flag...
flag.Parse()
//More code to execute the method given on the Args...
// something like $program test:hello -name "Peter"
}
I've tried every way I have found in the docs to 1) Get the pointer and 2) Make the Type assertion to *string, apparently I can do either or, but not both. There must be an easy syntax problem I do not know about.
Hope someone can help.
Kudos!