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  }