diff options
| author | Dave Henderson <dhenderson@gmail.com> | 2018-04-18 23:32:40 -0400 |
|---|---|---|
| committer | Dave Henderson <dhenderson@gmail.com> | 2018-04-18 23:32:40 -0400 |
| commit | b061d82c7be5ba8f5c17752e52576018f7c98d3c (patch) | |
| tree | 4aaef406914486b3705eb9d7a5f87b1e2bf0ba99 /conv/evalargs.go | |
| parent | 2aea441c387d9f01ea857019d091be24072a4bd7 (diff) | |
Adding conv.ToString function
Signed-off-by: Dave Henderson <dhenderson@gmail.com>
Diffstat (limited to 'conv/evalargs.go')
| -rw-r--r-- | conv/evalargs.go | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/conv/evalargs.go b/conv/evalargs.go new file mode 100644 index 00000000..b802e13d --- /dev/null +++ b/conv/evalargs.go @@ -0,0 +1,45 @@ +package conv + +// stolen from the Go standard library, text/template package. +import ( + "fmt" + "reflect" +) + +var ( + errorType = reflect.TypeOf((*error)(nil)).Elem() + fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem() +) + +// 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 +} + +// indirect returns the item at the end of indirection, and a bool to indicate if it's nil. +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 + } + } + return v, false +} |
