diff --git a/binding/form_mapping.go b/binding/form_mapping.go index 6982fd4f..53906106 100644 --- a/binding/form_mapping.go +++ b/binding/form_mapping.go @@ -201,7 +201,7 @@ func trySetCustom(val string, value reflect.Value) (isSet bool, err error) { func trySetUsingParser(val string, value reflect.Value, parser string) (isSet bool, err error) { switch parser { case "encoding.TextUnmarshaler": - v, ok := value.Addr().Interface().(encoding.TextUnmarshaler) + v, ok := reflect.TypeAssert[encoding.TextUnmarshaler](value) if !ok { return false, nil } diff --git a/binding/form_mapping_benchmark_test.go b/binding/form_mapping_benchmark_test.go index d40699e9..87bfea23 100644 --- a/binding/form_mapping_benchmark_test.go +++ b/binding/form_mapping_benchmark_test.go @@ -5,6 +5,7 @@ package binding import ( + "reflect" "testing" "time" @@ -65,3 +66,32 @@ func BenchmarkMapFormName(b *testing.B) { t := b assert.Equal(t, "mike", s.Name) } + +// customUnmarshalTextString is a custom type that implements encoding.TextUnmarshaler. +// It stores the unmarshaled text in the Value field. +type customUnmarshalTextString struct { + Value string +} + +func (t *customUnmarshalTextString) UnmarshalText(text []byte) error { + t.Value = string(text) + return nil +} + +// BenchmarkTrySetUsingParserTextUnmarshaler benchmarks the performance of trySetUsingParser +// when using the "encoding.TextUnmarshaler" parser to unmarshal a string value. +func BenchmarkTrySetUsingParserTextUnmarshaler(b *testing.B) { + var target customUnmarshalTextString + value := reflect.ValueOf(&target).Elem() + testValue := "hello world" + parser := "encoding.TextUnmarshaler" + + b.ResetTimer() + b.ReportAllocs() + for b.Loop() { + _, err := trySetUsingParser(testValue, value, parser) + if err != nil { + b.Fatal(err) + } + } +}