github.com/lastbackend/toolkit@v0.0.0-20241020043710-cafa37b95aad/pkg/runtime/controller/util.go (about) 1 package controller 2 3 import ( 4 "reflect" 5 ) 6 7 var ( 8 _typeOfError reflect.Type = reflect.TypeOf((*error)(nil)).Elem() 9 _nilError = reflect.Zero(_typeOfError) 10 ) 11 12 func build(target interface{}, kind interface{}) interface{} { 13 14 paramTypes, remap := parameters(target) 15 resultTypes, _ := currentResultTypes(target, kind) 16 17 origFn := reflect.ValueOf(target) 18 newFnType := reflect.FuncOf(paramTypes, resultTypes, false) 19 newFn := reflect.MakeFunc(newFnType, func(args []reflect.Value) []reflect.Value { 20 args = remap(args) 21 values := origFn.Call(args) 22 23 for _, v := range values { 24 values = append(values, v.Convert(reflect.TypeOf(kind).Elem())) 25 } 26 27 return values 28 }) 29 return newFn.Interface() 30 } 31 32 func buildPackage(target interface{}, kind interface{}) interface{} { 33 34 paramTypes, remap := parameters(target) 35 resultTypes, _ := currentResultTypes(target, kind) 36 37 origFn := reflect.ValueOf(target) 38 newFnType := reflect.FuncOf(paramTypes, resultTypes, false) 39 newFn := reflect.MakeFunc(newFnType, func(args []reflect.Value) []reflect.Value { 40 args = remap(args) 41 values := origFn.Call(args) 42 43 for _, v := range values { 44 rv := reflect.ValueOf(kind).Elem() 45 rv.FieldByName("Source").Set(v) 46 values = append(values, rv) 47 } 48 49 return values 50 }) 51 return newFn.Interface() 52 } 53 54 func currentResultTypes(target interface{}, kind interface{}) (resultTypes []reflect.Type, hasError bool) { 55 ft := reflect.TypeOf(target) 56 numOut := ft.NumOut() 57 resultTypes = make([]reflect.Type, numOut) 58 59 for i := 0; i < numOut; i++ { 60 resultTypes[i] = ft.Out(i) 61 if resultTypes[i] == _typeOfError && i == numOut-1 { 62 hasError = true 63 } 64 } 65 for i := 0; i < numOut; i++ { 66 resultTypes = append(resultTypes, reflect.TypeOf(kind).Elem()) 67 } 68 return resultTypes, hasError 69 } 70 71 func parameters(target interface{}) ( 72 types []reflect.Type, 73 remap func([]reflect.Value) []reflect.Value, 74 ) { 75 ft := reflect.TypeOf(target) 76 types = make([]reflect.Type, ft.NumIn()) 77 for i := 0; i < ft.NumIn(); i++ { 78 types[i] = ft.In(i) 79 } 80 81 return types, func(args []reflect.Value) []reflect.Value { 82 return args 83 } 84 }