| //This package is copied from Go library text/template. |
| //The original private functions indirect and printableValue |
| //are exported as public functions. |
| package template |
| |
| import ( |
| "fmt" |
| "reflect" |
| ) |
| |
| var Indirect = indirect |
| var PrintableValue = printableValue |
| |
| var ( |
| errorType = reflect.TypeOf((*error)(nil)).Elem() |
| fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem() |
| ) |
| |
| // indirect returns the item at the end of indirection, and a bool to indicate if it's nil. |
| // We indirect through pointers and empty interfaces (only) because |
| // non-empty interfaces have methods we might need. |
| func indirect(v reflect.Value) (rv reflect.Value, isNil bool) { |
| for ; v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface; v = v.Elem() { |
| if v.IsNil() { |
| return v, true |
| } |
| if v.Kind() == reflect.Interface && v.NumMethod() > 0 { |
| break |
| } |
| } |
| return v, false |
| } |
| |
| // printableValue returns the, possibly indirected, interface value inside v that |
| // is best for a call to formatted printer. |
| func printableValue(v reflect.Value) (interface{}, bool) { |
| if v.Kind() == reflect.Ptr { |
| v, _ = indirect(v) // fmt.Fprint handles nil. |
| } |
| if !v.IsValid() { |
| return "<no value>", true |
| } |
| |
| if !v.Type().Implements(errorType) && !v.Type().Implements(fmtStringerType) { |
| if v.CanAddr() && (reflect.PtrTo(v.Type()).Implements(errorType) || reflect.PtrTo(v.Type()).Implements(fmtStringerType)) { |
| v = v.Addr() |
| } else { |
| switch v.Kind() { |
| case reflect.Chan, reflect.Func: |
| return nil, false |
| } |
| } |
| } |
| return v.Interface(), true |
| } |
| |
| // canBeNil reports whether an untyped nil can be assigned to the type. See reflect.Zero. |
| func canBeNil(typ reflect.Type) bool { |
| switch typ.Kind() { |
| case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: |
| return true |
| } |
| return false |
| } |
| |
| // isTrue reports whether the value is 'true', in the sense of not the zero of its type, |
| // and whether the value has a meaningful truth value. |
| func isTrue(val reflect.Value) (truth, ok bool) { |
| if !val.IsValid() { |
| // Something like var x interface{}, never set. It's a form of nil. |
| return false, true |
| } |
| switch val.Kind() { |
| case reflect.Array, reflect.Map, reflect.Slice, reflect.String: |
| truth = val.Len() > 0 |
| case reflect.Bool: |
| truth = val.Bool() |
| case reflect.Complex64, reflect.Complex128: |
| truth = val.Complex() != 0 |
| case reflect.Chan, reflect.Func, reflect.Ptr, reflect.Interface: |
| truth = !val.IsNil() |
| case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: |
| truth = val.Int() != 0 |
| case reflect.Float32, reflect.Float64: |
| truth = val.Float() != 0 |
| case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: |
| truth = val.Uint() != 0 |
| case reflect.Struct: |
| truth = true // Struct values are always true. |
| default: |
| return |
| } |
| return truth, true |
| } |