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 }