github.com/enmand/kubernetes@v1.2.0-alpha.0/third_party/golang/template/exec.go (about)

     1  //This package is copied from Go library text/template.
     2  //The original private functions indirect and printableValue
     3  //are exported as public functions.
     4  package template
     5  
     6  import (
     7  	"fmt"
     8  	"reflect"
     9  )
    10  
    11  var Indirect = indirect
    12  var PrintableValue = printableValue
    13  
    14  var (
    15  	errorType       = reflect.TypeOf((*error)(nil)).Elem()
    16  	fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
    17  )
    18  
    19  // indirect returns the item at the end of indirection, and a bool to indicate if it's nil.
    20  // We indirect through pointers and empty interfaces (only) because
    21  // non-empty interfaces have methods we might need.
    22  func indirect(v reflect.Value) (rv reflect.Value, isNil bool) {
    23  	for ; v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface; v = v.Elem() {
    24  		if v.IsNil() {
    25  			return v, true
    26  		}
    27  		if v.Kind() == reflect.Interface && v.NumMethod() > 0 {
    28  			break
    29  		}
    30  	}
    31  	return v, false
    32  }
    33  
    34  // printableValue returns the, possibly indirected, interface value inside v that
    35  // is best for a call to formatted printer.
    36  func printableValue(v reflect.Value) (interface{}, bool) {
    37  	if v.Kind() == reflect.Ptr {
    38  		v, _ = indirect(v) // fmt.Fprint handles nil.
    39  	}
    40  	if !v.IsValid() {
    41  		return "<no value>", true
    42  	}
    43  
    44  	if !v.Type().Implements(errorType) && !v.Type().Implements(fmtStringerType) {
    45  		if v.CanAddr() && (reflect.PtrTo(v.Type()).Implements(errorType) || reflect.PtrTo(v.Type()).Implements(fmtStringerType)) {
    46  			v = v.Addr()
    47  		} else {
    48  			switch v.Kind() {
    49  			case reflect.Chan, reflect.Func:
    50  				return nil, false
    51  			}
    52  		}
    53  	}
    54  	return v.Interface(), true
    55  }
    56  
    57  // canBeNil reports whether an untyped nil can be assigned to the type. See reflect.Zero.
    58  func canBeNil(typ reflect.Type) bool {
    59  	switch typ.Kind() {
    60  	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
    61  		return true
    62  	}
    63  	return false
    64  }
    65  
    66  // isTrue reports whether the value is 'true', in the sense of not the zero of its type,
    67  // and whether the value has a meaningful truth value.
    68  func isTrue(val reflect.Value) (truth, ok bool) {
    69  	if !val.IsValid() {
    70  		// Something like var x interface{}, never set. It's a form of nil.
    71  		return false, true
    72  	}
    73  	switch val.Kind() {
    74  	case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
    75  		truth = val.Len() > 0
    76  	case reflect.Bool:
    77  		truth = val.Bool()
    78  	case reflect.Complex64, reflect.Complex128:
    79  		truth = val.Complex() != 0
    80  	case reflect.Chan, reflect.Func, reflect.Ptr, reflect.Interface:
    81  		truth = !val.IsNil()
    82  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
    83  		truth = val.Int() != 0
    84  	case reflect.Float32, reflect.Float64:
    85  		truth = val.Float() != 0
    86  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
    87  		truth = val.Uint() != 0
    88  	case reflect.Struct:
    89  		truth = true // Struct values are always true.
    90  	default:
    91  		return
    92  	}
    93  	return truth, true
    94  }