I know reflection is generally frowned upon in go but for my current purposes Im pretty sure it is the best solution.
Essentially my project is cli tool which will output an xml query based on incoming commands and return the corresponding result.
There is some boiler plate code for each command request where default values are populated and supplied values validated.
So I have a series of Command objects based on a Command struct as follows:
type Command struct {
Name string
Request interface{}
RequestType reflect.Type
Response interface{}
RegisterFunc func(parentCmd *cobra.Command, cmd *Command) error
}
For the most part I really don't care about the types of the request/response (just xml encode/decode). However I need to briefly cast it to a concrete type to validate with struct annotations So for example I might do something like this:
var ccReq *CreateCredentialRequest
var set bool
if ccReq, set = command.Request.(*CreateCredentialRequest); !set {
log.Fatal(errors.New("invalid request type"))
}
result, err := govalidator.ValidateStruct(ccReq)
if err != nil {
println("error: " + err.Error())
os.Exit(1)
}
However in an ideal would I would like to handle this generically for all commands, something like this:
var ccReq *CreateCredentialRequest
var set bool
if ccReq, set = command.Request.(command.RequestType); !set {
log.Fatal(errors.New("invalid request type"))
}
However this results in the error:
command.RequestType is not a type
So, how can I store the value of a type for a later type assertion
Note: Following discussion in comments with JimB it seems that i do not actually need the concrete type for validation purposes (interface is fine) but I still need further down to assert the response type to provide a custom response handler