diff --git a/bindstring.go b/bindstring.go index 764036d..28ba58a 100644 --- a/bindstring.go +++ b/bindstring.go @@ -33,6 +33,11 @@ import ( func BindStringToObject(src string, dst interface{}) error { var err error + // Check if the destination implements Binder interface before any reflection + if binder, ok := dst.(Binder); ok { + return binder.Bind(src) + } + v := reflect.ValueOf(dst) t := reflect.TypeOf(dst) @@ -107,11 +112,6 @@ func BindStringToObject(src string, dst interface{}) error { } fallthrough case reflect.Struct: - // if this is not of type Time or of type Date look to see if this is of type Binder. - if dstType, ok := dst.(Binder); ok { - return dstType.Bind(src) - } - if t.ConvertibleTo(reflect.TypeOf(time.Time{})) { // Don't fail on empty string. if src == "" { diff --git a/bindstring_test.go b/bindstring_test.go index d3c4909..f695db1 100644 --- a/bindstring_test.go +++ b/bindstring_test.go @@ -24,6 +24,16 @@ import ( "github.com/oapi-codegen/runtime/types" ) +// CustomStringBinder is a string type that implements Binder but not TextUnmarshaler +// This tests that Binder interface is checked for primitive types +type CustomStringBinder string + +func (c *CustomStringBinder) Bind(src string) error { + // Custom binding logic: add a prefix to demonstrate the Bind method was called + *c = CustomStringBinder("CUSTOM:" + src) + return nil +} + func TestBindStringToObject(t *testing.T) { var i int assert.NoError(t, BindStringToObject("5", &i)) @@ -209,4 +219,10 @@ func TestBindStringToObject(t *testing.T) { assert.NoError(t, BindStringToObject(uuidString, &dstUUID)) assert.Equal(t, dstUUID.String(), uuidString) + // Checks that primitive types implementing Binder are respected + // This tests the fix for ensuring Binder is checked before type reflection + var customString CustomStringBinder + assert.NoError(t, BindStringToObject("hello", &customString)) + assert.Equal(t, CustomStringBinder("CUSTOM:hello"), customString) + }