This commit is contained in:
2026-01-28 12:43:17 -05:00
parent f9d3753806
commit 604178341d
10 changed files with 188 additions and 172 deletions

View File

@@ -2,24 +2,75 @@ package builtin
import (
"context"
"errors"
"reflect"
)
type Builtin struct {
Name string
Function interface{}
Definition string
Types []string
ParamTypes map[string]bool
type Builtin interface {
Name() string
Types() []string
Definition() string
WrapFn(context.Context) func(...any) (any, error)
}
func (b *Builtin) HasParamType(typeName string) bool {
return b.ParamTypes[typeName]
}
type EmptyArgs struct{}
type Func[A Args, R any] func(ctx context.Context, args A) (R, error)
type Args interface {
Validate() error
}
type Func[T Args, R any] func(ctx context.Context, args T) (R, error)
type builtinImpl[A Args, R any] struct {
name string
fn Func[A, R]
definition string
types []string
}
func (b *builtinImpl[A, R]) Name() string {
return b.name
}
func (b *builtinImpl[A, R]) Types() []string {
return b.types
}
func (b *builtinImpl[A, R]) Definition() string {
return b.definition
}
func (b *builtinImpl[A, R]) WrapFn(ctx context.Context) func(...any) (any, error) {
return func(allArgs ...any) (any, error) {
// Populate Arguments
var fnArgs A
aVal := reflect.ValueOf(&fnArgs).Elem()
// Populate Fields
for i := range min(aVal.NumField(), len(allArgs)) {
field := aVal.Field(i)
if !field.CanSet() {
return nil, errors.New("cannot set field")
}
argVal := reflect.ValueOf(allArgs[i])
if !argVal.Type().AssignableTo(field.Type()) {
return nil, errors.New("cannot assign field")
}
field.Set(argVal)
}
// Validate
if err := fnArgs.Validate(); err != nil {
return nil, errors.New("cannot validate args")
}
// Call Function
resp, err := b.fn(ctx, fnArgs)
if err != nil {
return nil, err
}
return resp, nil
}
}