Defaulted .ToStringE to use reflection to find a stringer element

This commit is contained in:
Derek Perkins 2014-12-09 08:12:03 -07:00 committed by spf13
parent 0a58809502
commit c0388c79a0
1 changed files with 11 additions and 1 deletions

View File

@ -119,6 +119,11 @@ func ToIntE(i interface{}) (int, error) {
} }
} }
var (
errorType = reflect.TypeOf((*error)(nil)).Elem()
fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
)
func ToStringE(i interface{}) (string, error) { func ToStringE(i interface{}) (string, error) {
jww.DEBUG.Println("ToStringE called on type:", reflect.TypeOf(i)) jww.DEBUG.Println("ToStringE called on type:", reflect.TypeOf(i))
@ -136,7 +141,12 @@ func ToStringE(i interface{}) (string, error) {
case nil: case nil:
return "", nil return "", nil
default: default:
return "", fmt.Errorf("Unable to Cast %#v to string", i) // shamelessly borrowed from html/template
v := reflect.ValueOf(i)
for !v.Type().Implements(fmtStringerType) && !v.Type().Implements(errorType) && v.Kind() == reflect.Ptr && !v.IsNil() {
v = v.Elem()
}
return fmt.Sprint(v), nil
} }
} }