From 421411cf354fa9b6cfae5ca214dbefe6b3323746 Mon Sep 17 00:00:00 2001 From: spf13 Date: Wed, 31 Dec 2014 23:48:55 -0500 Subject: [PATCH] Add proper support for error -> string and Stringer -> string. --- cast_test.go | 32 +++++++++++++++++++++++++++++++- caste.go | 15 +++++---------- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/cast_test.go b/cast_test.go index 13318a4..e8cb176 100644 --- a/cast_test.go +++ b/cast_test.go @@ -8,8 +8,9 @@ package cast import ( "testing" - "github.com/stretchr/testify/assert" "html/template" + + "github.com/stretchr/testify/assert" ) func TestToInt(t *testing.T) { @@ -40,6 +41,35 @@ func TestToString(t *testing.T) { assert.Equal(t, ToString(nil), "") } +type foo struct { + val string +} + +func (x foo) String() string { + return x.val +} + +func TestStringerToString(t *testing.T) { + + var x foo + x.val = "bar" + assert.Equal(t, "bar", ToString(x)) +} + +type fu struct { + val string +} + +func (x fu) Error() string { + return x.val +} + +func TestErrorToString(t *testing.T) { + var x fu + x.val = "bar" + assert.Equal(t, "bar", ToString(x)) +} + func TestMaps(t *testing.T) { var taxonomies = map[interface{}]interface{}{"tag": "tags", "group": "groups"} var stringMapBool = map[interface{}]interface{}{"v1": true, "v2": false} diff --git a/caste.go b/caste.go index d639da7..40bde04 100644 --- a/caste.go +++ b/caste.go @@ -119,10 +119,6 @@ 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) { jww.DEBUG.Println("ToStringE called on type:", reflect.TypeOf(i)) @@ -140,13 +136,12 @@ func ToStringE(i interface{}) (string, error) { return string(s), nil case nil: return "", nil + case fmt.Stringer: + return s.String(), nil + case error: + return s.Error(), nil default: - // 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 + return "", fmt.Errorf("Unable to Cast %#v to string", i) } }