k8s.io/client-go@v0.31.1/third_party/forked/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 ( 12 errorType = reflect.TypeOf((*error)(nil)).Elem() 13 fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem() 14 ) 15 16 // Indirect returns the item at the end of indirection, and a bool to indicate if it's nil. 17 // We indirect through pointers and empty interfaces (only) because 18 // non-empty interfaces have methods we might need. 19 func Indirect(v reflect.Value) (rv reflect.Value, isNil bool) { 20 for ; v.Kind() == reflect.Pointer || v.Kind() == reflect.Interface; v = v.Elem() { 21 if v.IsNil() { 22 return v, true 23 } 24 if v.Kind() == reflect.Interface && v.NumMethod() > 0 { 25 break 26 } 27 } 28 return v, false 29 } 30 31 // PrintableValue returns the, possibly indirected, interface value inside v that 32 // is best for a call to formatted printer. 33 func PrintableValue(v reflect.Value) (interface{}, bool) { 34 if v.Kind() == reflect.Pointer { 35 v, _ = Indirect(v) // fmt.Fprint handles nil. 36 } 37 if !v.IsValid() { 38 return "<no value>", true 39 } 40 41 if !v.Type().Implements(errorType) && !v.Type().Implements(fmtStringerType) { 42 if v.CanAddr() && (reflect.PointerTo(v.Type()).Implements(errorType) || reflect.PointerTo(v.Type()).Implements(fmtStringerType)) { 43 v = v.Addr() 44 } else { 45 switch v.Kind() { 46 case reflect.Chan, reflect.Func: 47 return nil, false 48 } 49 } 50 } 51 return v.Interface(), true 52 }