Implement type-to-string-to-type mappings

This commit is contained in:
Ryan McGuire 2024-11-26 20:18:10 -05:00
parent c9d3b534de
commit 447e6d842e
3 changed files with 2203 additions and 2181 deletions

File diff suppressed because it is too large Load Diff

View File

@ -19,13 +19,6 @@ const (
const tmplParseFuncs = `package ` + packageName + `
import (
"context"
"io"
"net/http"
"reflect"
)
// Generated map of Parse functions to support
// dynamic reflection upon parser functions
var ParseFunctionsMap = map[string]interface{}{
@ -41,15 +34,30 @@ type FunctionParamInfo struct {
}
const tmplFuncParams = `
var FunctionParams = map[string][]reflect.Type{
// List of functions in eiaapi package
// with slice of arg types as strings
var FunctionParams = map[string][]string{
{{- range .}}
"{{ .FunctionName }}": {
{{- range .Params }}
reflect.TypeOf((*{{ . }})(nil)).Elem(),
{{ . | printf "\"%s\"" }},
{{- end }}
},
{{- end}}
}
func GetFuncParamType(funcName string, idx int) string {
funcParams, exists := FunctionParams[funcName]
if !exists {
return ""
}
if idx < len(funcParams) {
return funcParams[idx]
}
return ""
}
`
func main() {
@ -137,7 +145,7 @@ func exprToString(expr ast.Expr) string {
case *ast.ArrayType:
return "[]" + exprToString(t.Elt) // Array type
case *ast.StarExpr:
return exprToString(t.X) // Pointer type
return "*" + exprToString(t.X) // Pointer type
case *ast.SelectorExpr:
return fmt.Sprintf("%s.%s", exprToString(t.X), t.Sel.Name) // Qualified type like "pkg.Type"
case *ast.FuncType:

View File

@ -18,6 +18,7 @@ import (
// parameters by type
type MethodSubs struct {
TypedParams map[reflect.Type]reflect.Value // Replace field of specific type with value, must be ptr to type
StrTypedParams map[string]reflect.Value // Parameter types by string name from eiaapi mappings
RequestEditorFns []eiaapi.RequestEditorFn // Optional request editor functions
}
@ -25,9 +26,13 @@ type MethodSubs struct {
// To be more specific, set NameParams, which will overwrite
// NameContainsParams
var defaultMethodSubs = MethodSubs{
TypedParams: map[reflect.Type]reflect.Value{
reflect.TypeOf((*eiaapi.Route1)(nil)): reflect.ValueOf(
strconv.Itoa(time.Now().AddDate(-1, 0, 0).Year())),
StrTypedParams: map[string]reflect.Value{
"Route1": reflect.ValueOf(eiaapi.Route1(
strconv.Itoa(time.Now().AddDate(-1, 0, 0).Year()),
)),
"Route2": reflect.ValueOf(eiaapi.Route1(
strconv.Itoa(time.Now().AddDate(-1, 0, 0).Year()),
)),
},
}
@ -42,8 +47,7 @@ func (client *Client) GetFacet(ctx context.Context, route string, facet string,
return nil, fmt.Errorf("method %s not found", methodName)
}
// Populate facet param anywhere in func call
subs.TypedParams[reflect.TypeOf((*eiaapi.FacetId)(nil))] = reflect.ValueOf(facet)
subs.StrTypedParams["FacetId"] = reflect.ValueOf(eiaapi.FacetId(facet))
args := prepMethodArgs(method, methodName, subs)
@ -174,7 +178,9 @@ func (client *Client) GetFacets(ctx context.Context, route string, subs *MethodS
func DefaultMethodSubs(ctx context.Context) *MethodSubs {
subs := defaultMethodSubs
subs.TypedParams[reflect.TypeOf((*context.Context)(nil)).Elem()] = reflect.ValueOf(ctx)
subs.TypedParams = map[reflect.Type]reflect.Value{
reflect.TypeOf((*context.Context)(nil)).Elem(): reflect.ValueOf(ctx),
}
return &subs
}
@ -226,18 +232,14 @@ func prepMethodArgs(method reflect.Value, name string, subs *MethodSubs) []refle
break
}
// Retrieve arg from generated arg mapping due to use of
// type aliases (e.g. type Route1 = string) rather than use of
// discrete types (e.g. type Route1 string) in generated code
funcArgs, ok := eiaapi.FunctionParams[name]
if ok {
if i > len(funcArgs) {
// WARN: This indicates a generator issues
} else {
argType = funcArgs[i]
// Perform type lookups by string match
if paramType := eiaapi.GetFuncParamType(name, i); paramType != "" {
for name, val := range subs.StrTypedParams {
if paramType == name {
args = append(args, val)
goto next
}
}
} else {
// WARN: This indicates a generator issues
}
// Run through type substitutions