Add proper support for error -> string and Stringer -> string.

This commit is contained in:
spf13 2014-12-31 23:48:55 -05:00
parent c0388c79a0
commit 421411cf35
2 changed files with 36 additions and 11 deletions

View File

@ -8,8 +8,9 @@ package cast
import ( import (
"testing" "testing"
"github.com/stretchr/testify/assert"
"html/template" "html/template"
"github.com/stretchr/testify/assert"
) )
func TestToInt(t *testing.T) { func TestToInt(t *testing.T) {
@ -40,6 +41,35 @@ func TestToString(t *testing.T) {
assert.Equal(t, ToString(nil), "") 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) { func TestMaps(t *testing.T) {
var taxonomies = map[interface{}]interface{}{"tag": "tags", "group": "groups"} var taxonomies = map[interface{}]interface{}{"tag": "tags", "group": "groups"}
var stringMapBool = map[interface{}]interface{}{"v1": true, "v2": false} var stringMapBool = map[interface{}]interface{}{"v1": true, "v2": false}

View File

@ -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) { 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))
@ -140,13 +136,12 @@ func ToStringE(i interface{}) (string, error) {
return string(s), nil return string(s), nil
case nil: case nil:
return "", nil return "", nil
case fmt.Stringer:
return s.String(), nil
case error:
return s.Error(), nil
default: default:
// shamelessly borrowed from html/template return "", fmt.Errorf("Unable to Cast %#v to string", i)
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
} }
} }