...

Source file src/github.com/thoas/go-funk/utils.go

Documentation: github.com/thoas/go-funk

     1  package funk
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  )
     7  
     8  func equal(expectedOrPredicate interface{}, optionalIsMap ...bool) func(keyValueIfMap, actualValue reflect.Value) bool {
     9  	isMap := append(optionalIsMap, false)[0]
    10  
    11  	if IsFunction(expectedOrPredicate) {
    12  		inTypes := []reflect.Type{nil}; if isMap {
    13  			inTypes = append(inTypes, nil)
    14  		}
    15  
    16  		if !IsPredicate(expectedOrPredicate, inTypes...) {
    17  			panic(fmt.Sprintf("Predicate function must have %d parameter and must return boolean", len(inTypes)))
    18  		}
    19  
    20  		predicateValue := reflect.ValueOf(expectedOrPredicate)
    21  
    22  		return func(keyValueIfMap, actualValue reflect.Value) bool {
    23  
    24  			if isMap && !keyValueIfMap.Type().ConvertibleTo(predicateValue.Type().In(0)) {
    25  				panic("Given key is not compatible with type of parameter for the predicate.")
    26  			}
    27  
    28  			if (isMap && !actualValue.Type().ConvertibleTo(predicateValue.Type().In(1))) ||
    29  				(!isMap && !actualValue.Type().ConvertibleTo(predicateValue.Type().In(0))) {
    30  				panic("Given value is not compatible with type of parameter for the predicate.")
    31  			}
    32  
    33  			args := []reflect.Value{actualValue}
    34  			if isMap {
    35  				args = append([]reflect.Value{keyValueIfMap}, args...)
    36  			}
    37  
    38  			return predicateValue.Call(args)[0].Bool()
    39  		}
    40  	}
    41  
    42  	expected := expectedOrPredicate
    43  
    44  	return func(keyValueIfMap, actualValue reflect.Value) bool {
    45  		if isMap {
    46  			actualValue = keyValueIfMap
    47  		}
    48  
    49  		if expected == nil || actualValue.IsZero() {
    50  			return actualValue.Interface() == expected
    51  		}
    52  
    53  		return reflect.DeepEqual(actualValue.Interface(), expected)
    54  	}
    55  }
    56  
    57  func sliceElem(rtype reflect.Type) reflect.Type {
    58  	for {
    59  		if rtype.Kind() != reflect.Slice && rtype.Kind() != reflect.Array {
    60  			return rtype
    61  		}
    62  
    63  		rtype = rtype.Elem()
    64  	}
    65  }
    66  
    67  func redirectValue(value reflect.Value) reflect.Value {
    68  	for {
    69  		if !value.IsValid() || (value.Kind() != reflect.Ptr && value.Kind() != reflect.Interface) {
    70  			return value
    71  		}
    72  
    73  		res := value.Elem()
    74  
    75  		// Test for a circular type.
    76  		if res.Kind() == reflect.Ptr && value.Kind() == reflect.Ptr && value.Pointer() == res.Pointer() {
    77  			return value
    78  		}
    79  
    80  		if !res.IsValid() && value.Kind() == reflect.Ptr {
    81  			return reflect.Zero(value.Type().Elem())
    82  		}
    83  
    84  		value = res
    85  	}
    86  }
    87  
    88  func makeSlice(value reflect.Value, values ...int) reflect.Value {
    89  	sliceType := sliceElem(value.Type())
    90  
    91  	size := value.Len()
    92  	cap := size
    93  
    94  	if len(values) > 0 {
    95  		size = values[0]
    96  	}
    97  
    98  	if len(values) > 1 {
    99  		cap = values[1]
   100  	}
   101  
   102  	return reflect.MakeSlice(reflect.SliceOf(sliceType), size, cap)
   103  }
   104  

View as plain text