Start busting out reflection for GetFacet
This commit is contained in:
parent
d30506839a
commit
72186843b4
@ -14,6 +14,21 @@ import (
|
|||||||
eiaapi "gitea.libretechconsulting.com/50W/eia-api-go/api"
|
eiaapi "gitea.libretechconsulting.com/50W/eia-api-go/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type MethodSubs struct {
|
||||||
|
TypedParams map[reflect.Type]reflect.Value // Replace field of specific type with value
|
||||||
|
NameParams map[string]reflect.Value // Replace field with specific name with value
|
||||||
|
NameContainsParams map[string]reflect.Value // Replace fields with name containing string with value
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultMethodSubs = MethodSubs{
|
||||||
|
NameContainsParams: map[string]reflect.Value{
|
||||||
|
"route": reflect.ValueOf(strconv.Itoa(time.Now().AddDate(-1, 0, 0).Year())),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// func GetFacet(cmd *cobra.Command, route string) (*eiaapi.FacetOptionList, error) {
|
||||||
|
// }
|
||||||
|
|
||||||
func GetFacets(cmd *cobra.Command, route string) (*eiaapi.FacetOptionList, error) {
|
func GetFacets(cmd *cobra.Command, route string) (*eiaapi.FacetOptionList, error) {
|
||||||
client, err := Client(cmd)
|
client, err := Client(cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -29,49 +44,9 @@ func GetFacets(cmd *cobra.Command, route string) (*eiaapi.FacetOptionList, error
|
|||||||
return nil, fmt.Errorf("method %q not found", route)
|
return nil, fmt.Errorf("method %q not found", route)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a slice of reflect.Value for the method's arguments
|
args := prepMethodArgs(cmd.Context(), method, GetMethodSubs(cmd))
|
||||||
methodType := method.Type()
|
|
||||||
args := make([]reflect.Value, 0, methodType.NumIn())
|
|
||||||
|
|
||||||
// Populate arguments with zero values for their respective types
|
|
||||||
for i := 0; i < methodType.NumIn(); i++ {
|
|
||||||
argType := methodType.In(i)
|
|
||||||
|
|
||||||
// Don't supply request editor Fn args
|
|
||||||
if methodType.IsVariadic() && i == methodType.NumIn()-1 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if argType == reflect.TypeOf((*context.Context)(nil)).Elem() {
|
|
||||||
args = append(args, reflect.ValueOf(cmd.Context()))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default to last year for Route1
|
|
||||||
if argType == reflect.TypeOf(eiaapi.Route1("1999")) {
|
|
||||||
lastYear := time.Now().AddDate(-1, 0, 0).Year()
|
|
||||||
args = append(args, reflect.ValueOf(eiaapi.Route1(strconv.Itoa(lastYear))))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Zero value of other stuff
|
|
||||||
args = append(args, reflect.Zero(argType))
|
|
||||||
}
|
|
||||||
|
|
||||||
results := method.Call(args)
|
|
||||||
if len(results) != 2 {
|
|
||||||
return nil, errors.New("unexpected response from get facet call")
|
|
||||||
}
|
|
||||||
|
|
||||||
var resp *http.Response
|
|
||||||
var ok bool
|
|
||||||
if resp, ok = results[0].Interface().(*http.Response); !ok {
|
|
||||||
return nil, errors.New("no or invalid response received from call")
|
|
||||||
}
|
|
||||||
if err := checkCallErr(results[1]); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Prepare a parser func for our facet response
|
||||||
parserFunc, exists := eiaapi.ParseFunctionsMap[fmt.Sprintf("Parse%sResponse", route)]
|
parserFunc, exists := eiaapi.ParseFunctionsMap[fmt.Sprintf("Parse%sResponse", route)]
|
||||||
if !exists {
|
if !exists {
|
||||||
return nil, fmt.Errorf("parser func for %s not found", route)
|
return nil, fmt.Errorf("parser func for %s not found", route)
|
||||||
@ -82,6 +57,21 @@ func GetFacets(cmd *cobra.Command, route string) (*eiaapi.FacetOptionList, error
|
|||||||
return nil, errors.New("unable to find parser for facet response")
|
return nil, errors.New("unable to find parser for facet response")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Perform the API call
|
||||||
|
results := method.Call(args)
|
||||||
|
if len(results) != 2 {
|
||||||
|
return nil, errors.New("unexpected response from get facet call")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare *http.Response, error
|
||||||
|
resp, err := getResponse(results)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call the parser with our response, then extract the JSON200 response,
|
||||||
|
// and return the expected FacetOptiionsList from the container
|
||||||
|
|
||||||
results = parser.Call([]reflect.Value{reflect.ValueOf(resp)})
|
results = parser.Call([]reflect.Value{reflect.ValueOf(resp)})
|
||||||
if len(results) != 2 {
|
if len(results) != 2 {
|
||||||
return nil, errors.New("unexpected response while parsing facet response")
|
return nil, errors.New("unexpected response while parsing facet response")
|
||||||
@ -116,6 +106,55 @@ func GetFacets(cmd *cobra.Command, route string) (*eiaapi.FacetOptionList, error
|
|||||||
return facetOptions.Response, nil
|
return facetOptions.Response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Given an API method, replaces any named fields with the provided value
|
||||||
|
// from the subs map, otherwise uses built-in logic for common fields
|
||||||
|
// such as a context.Context. Skips request editor funcs
|
||||||
|
func prepMethodArgs(ctx context.Context, method reflect.Value, _ MethodSubs) []reflect.Value {
|
||||||
|
// Create a slice of reflect.Value for the method's arguments
|
||||||
|
methodType := method.Type()
|
||||||
|
args := make([]reflect.Value, 0, methodType.NumIn())
|
||||||
|
|
||||||
|
// Populate arguments with zero values for their respective types
|
||||||
|
for i := 0; i < methodType.NumIn(); i++ {
|
||||||
|
argType := methodType.In(i)
|
||||||
|
|
||||||
|
// Don't supply request editor Fn args
|
||||||
|
if methodType.IsVariadic() && i == methodType.NumIn()-1 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if argType == reflect.TypeOf((*context.Context)(nil)).Elem() {
|
||||||
|
args = append(args, reflect.ValueOf(ctx))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default to last year for Route1
|
||||||
|
if argType == reflect.TypeOf(eiaapi.Route1("1999")) {
|
||||||
|
lastYear := time.Now().AddDate(-1, 0, 0).Year()
|
||||||
|
args = append(args, reflect.ValueOf(eiaapi.Route1(strconv.Itoa(lastYear))))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zero value of other stuff
|
||||||
|
args = append(args, reflect.Zero(argType))
|
||||||
|
}
|
||||||
|
|
||||||
|
return args
|
||||||
|
}
|
||||||
|
|
||||||
|
func getResponse(responses []reflect.Value) (*http.Response, error) {
|
||||||
|
resp, ok := responses[0].Interface().(*http.Response)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("no or invalid response received from call")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := checkCallErr(responses[1]); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
func checkCallErr(val reflect.Value) error {
|
func checkCallErr(val reflect.Value) error {
|
||||||
var err error
|
var err error
|
||||||
var ok bool
|
var ok bool
|
||||||
@ -128,3 +167,11 @@ func checkCallErr(val reflect.Value) error {
|
|||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetMethodSubs(cmd *cobra.Command) MethodSubs {
|
||||||
|
subs := defaultMethodSubs
|
||||||
|
|
||||||
|
subs.TypedParams[reflect.TypeOf(context.Background())] = reflect.ValueOf(cmd.Context())
|
||||||
|
|
||||||
|
return subs
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user