Add support for pointers to basic types
diff --git a/cast_test.go b/cast_test.go
index e8cb176..c428ba5 100644
--- a/cast_test.go
+++ b/cast_test.go
@@ -97,3 +97,12 @@
assert.Equal(t, ToBool(true), true)
assert.Equal(t, ToBool(-1), true)
}
+
+func TestIndirectPointers(t *testing.T) {
+ x := 13
+ y := &x
+ z := &y
+
+ assert.Equal(t, ToInt(y), 13)
+ assert.Equal(t, ToInt(z), 13)
+}
diff --git a/caste.go b/caste.go
index 40bde04..d55b85b 100644
--- a/caste.go
+++ b/caste.go
@@ -17,6 +17,7 @@
)
func ToTimeE(i interface{}) (tim time.Time, err error) {
+ i = indirect(i)
jww.DEBUG.Println("ToTimeE called on type:", reflect.TypeOf(i))
switch s := i.(type) {
@@ -34,6 +35,7 @@
}
func ToBoolE(i interface{}) (bool, error) {
+ i = indirect(i)
jww.DEBUG.Println("ToBoolE called on type:", reflect.TypeOf(i))
switch b := i.(type) {
@@ -54,6 +56,7 @@
}
func ToFloat64E(i interface{}) (float64, error) {
+ i = indirect(i)
jww.DEBUG.Println("ToFloat64E called on type:", reflect.TypeOf(i))
switch s := i.(type) {
@@ -84,6 +87,7 @@
}
func ToIntE(i interface{}) (int, error) {
+ i = indirect(i)
jww.DEBUG.Println("ToIntE called on type:", reflect.TypeOf(i))
switch s := i.(type) {
@@ -119,8 +123,47 @@
}
}
+// From html/template/content.go
+// Copyright 2011 The Go Authors. All rights reserved.
+// indirect returns the value, after dereferencing as many times
+// as necessary to reach the base type (or nil).
+func indirect(a interface{}) interface{} {
+ if a == nil {
+ return nil
+ }
+ if t := reflect.TypeOf(a); t.Kind() != reflect.Ptr {
+ // Avoid creating a reflect.Value if it's not a pointer.
+ return a
+ }
+ v := reflect.ValueOf(a)
+ for v.Kind() == reflect.Ptr && !v.IsNil() {
+ v = v.Elem()
+ }
+ return v.Interface()
+}
+
+// From html/template/content.go
+// Copyright 2011 The Go Authors. All rights reserved.
+// indirectToStringerOrError returns the value, after dereferencing as many times
+// as necessary to reach the base type (or nil) or an implementation of fmt.Stringer
+// or error,
+func indirectToStringerOrError(a interface{}) interface{} {
+ if a == nil {
+ return nil
+ }
+
+ var errorType = reflect.TypeOf((*error)(nil)).Elem()
+ var fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
+
+ v := reflect.ValueOf(a)
+ for !v.Type().Implements(fmtStringerType) && !v.Type().Implements(errorType) && v.Kind() == reflect.Ptr && !v.IsNil() {
+ v = v.Elem()
+ }
+ return v.Interface()
+}
func ToStringE(i interface{}) (string, error) {
+ i = indirectToStringerOrError(i)
jww.DEBUG.Println("ToStringE called on type:", reflect.TypeOf(i))
switch s := i.(type) {