Implement reflection and list facets
This commit is contained in:
23
cmd/eia-client/internal/util/util_completion.go
Normal file
23
cmd/eia-client/internal/util/util_completion.go
Normal file
@ -0,0 +1,23 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"gitea.libretechconsulting.com/50W/eia-api-go/pkg/eia"
|
||||
)
|
||||
|
||||
func CompleteRoutes(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
routes := eia.GetRoutes()
|
||||
compRoutes := make([]string, 0, len(routes))
|
||||
|
||||
for _, r := range routes {
|
||||
if strings.HasPrefix(r, toComplete) {
|
||||
compRoutes = append(compRoutes, r)
|
||||
}
|
||||
}
|
||||
|
||||
return slices.Clip(compRoutes), cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
92
cmd/eia-client/internal/util/util_reflect.go
Normal file
92
cmd/eia-client/internal/util/util_reflect.go
Normal file
@ -0,0 +1,92 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
eiaapi "gitea.libretechconsulting.com/50W/eia-api-go/api"
|
||||
)
|
||||
|
||||
func GetFacets(cmd *cobra.Command, route string) (any, error) {
|
||||
client, err := Client(cmd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Get the reflect.Value of the target object
|
||||
targetValue := reflect.ValueOf(client)
|
||||
|
||||
// Get the method by name
|
||||
method := targetValue.MethodByName(route)
|
||||
if !method.IsValid() {
|
||||
return nil, fmt.Errorf("method %q not found", route)
|
||||
}
|
||||
|
||||
// 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(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
|
||||
err = nil
|
||||
|
||||
if resp, ok = results[0].Interface().(*http.Response); !ok {
|
||||
return nil, errors.New("no or invalid response received from call")
|
||||
}
|
||||
|
||||
if results[1].IsValid() && !results[1].IsNil() {
|
||||
if err, ok = results[1].Interface().(error); !ok {
|
||||
return nil, errors.New("unexpected call response")
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
parser := reflect.ValueOf(eiaapi).MethodByName(fmt.Sprintf("Parse%sResponse", route))
|
||||
if !parser.IsValid() {
|
||||
return nil, errors.New("unable to find parser for facet response")
|
||||
}
|
||||
|
||||
parser.Call([]reflect.Value{reflect.ValueOf(resp)})
|
||||
|
||||
return resp, nil
|
||||
}
|
Reference in New Issue
Block a user