summaryrefslogtreecommitdiff
path: root/conv/evalargs.go
diff options
context:
space:
mode:
authorDave Henderson <dhenderson@gmail.com>2018-04-18 23:32:40 -0400
committerDave Henderson <dhenderson@gmail.com>2018-04-18 23:32:40 -0400
commitb061d82c7be5ba8f5c17752e52576018f7c98d3c (patch)
tree4aaef406914486b3705eb9d7a5f87b1e2bf0ba99 /conv/evalargs.go
parent2aea441c387d9f01ea857019d091be24072a4bd7 (diff)
Adding conv.ToString function
Signed-off-by: Dave Henderson <dhenderson@gmail.com>
Diffstat (limited to 'conv/evalargs.go')
-rw-r--r--conv/evalargs.go45
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
+}