package builtin import ( "context" "errors" "reflect" ) type Builtin interface { Name() string Types() []string Definition() string WrapFn(context.Context) func(...any) (any, error) } type Func[A Args, R any] func(ctx context.Context, args A) (R, error) type Args interface { Validate() 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 } }