1 //This package is copied from Go library text/template.
2 //The original private functions indirect and printableValue
3 //are exported as public functions.
11 var Indirect = indirect
12 var PrintableValue = printableValue
15 errorType = reflect.TypeOf((*error)(nil)).Elem()
16 fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
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() {
27 if v.Kind() == reflect.Interface && v.NumMethod() > 0 {
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.
41 return "<no value>", true
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)) {
49 case reflect.Chan, reflect.Func:
54 return v.Interface(), true
57 // canBeNil reports whether an untyped nil can be assigned to the type. See reflect.Zero.
58 func canBeNil(typ reflect.Type) bool {
60 case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
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) {
70 // Something like var x interface{}, never set. It's a form of nil.
74 case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
78 case reflect.Complex64, reflect.Complex128:
79 truth = val.Complex() != 0
80 case reflect.Chan, reflect.Func, reflect.Ptr, reflect.Interface:
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
89 truth = true // Struct values are always true.