fix: failed binding composite type of uri param

Signed-off-by: thxCode <thxcode0824@gmail.com>
This commit is contained in:
thxCode 2022-11-23 18:26:30 +08:00
parent 80cd679c43
commit 3fd1743e66
5 changed files with 50 additions and 4 deletions

View File

@ -18,9 +18,11 @@ import (
"testing" "testing"
"time" "time"
"github.com/gin-gonic/gin/testdata/protoexample" "github.com/google/uuid"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"google.golang.org/protobuf/proto" "google.golang.org/protobuf/proto"
"github.com/gin-gonic/gin/testdata/protoexample"
) )
type appkey struct { type appkey struct {
@ -796,12 +798,15 @@ func TestUriBinding(t *testing.T) {
assert.Equal(t, "uri", b.Name()) assert.Equal(t, "uri", b.Name())
type Tag struct { type Tag struct {
Name string `uri:"name"` ID uuid.NullUUID `uri:"id"`
Name string `uri:"name"`
} }
var tag Tag var tag Tag
m := make(map[string][]string) m := make(map[string][]string)
m["id"] = []string{"5b620cc3-a5eb-4515-8fc7-4686d5cadfa9"}
m["name"] = []string{"thinkerou"} m["name"] = []string{"thinkerou"}
assert.NoError(t, b.BindUri(m, &tag)) assert.NoError(t, b.BindUri(m, &tag))
assert.Equal(t, uuid.NullUUID{Valid: true, UUID: uuid.MustParse("5b620cc3-a5eb-4515-8fc7-4686d5cadfa9")}, tag.ID)
assert.Equal(t, "thinkerou", tag.Name) assert.Equal(t, "thinkerou", tag.Name)
type NotSupportStruct struct { type NotSupportStruct struct {

View File

@ -236,9 +236,9 @@ func setWithProperType(val string, value reflect.Value, field reflect.StructFiel
case time.Time: case time.Time:
return setTimeField(val, field, value) return setTimeField(val, field, value)
} }
return json.Unmarshal(bytesconv.StringToBytes(val), value.Addr().Interface()) return json.Unmarshal(completeJSONBytes(bytesconv.StringToBytes(val)), value.Addr().Interface())
case reflect.Map: case reflect.Map:
return json.Unmarshal(bytesconv.StringToBytes(val), value.Addr().Interface()) return json.Unmarshal(completeJSONBytes(bytesconv.StringToBytes(val)), value.Addr().Interface())
default: default:
return errUnknownType return errUnknownType
} }
@ -401,3 +401,15 @@ func setFormMap(ptr any, form map[string][]string) error {
return nil return nil
} }
func completeJSONBytes(bs []byte) []byte {
if len(bs) == 0 ||
bs[0] == '"' && bs[len(bs)-1] == '"' {
return bs
}
var cbs = make([]byte, len(bs)+2)
cbs[0] = '"'
copy(cbs[1:], bs)
cbs[len(cbs)-1] = '"'
return cbs
}

View File

@ -9,6 +9,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/google/uuid"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -136,6 +137,31 @@ func TestMappingURI(t *testing.T) {
assert.Equal(t, 6, s.F) assert.Equal(t, 6, s.F)
} }
func TestMappingURICompositeTypes(t *testing.T) {
for _, tt := range []struct {
name string
value any
uri string
expect any
}{
{"uuid", struct{ F uuid.NullUUID }{}, "5b620cc3-a5eb-4515-8fc7-4686d5cadfa9", uuid.NullUUID{Valid: true, UUID: uuid.MustParse("5b620cc3-a5eb-4515-8fc7-4686d5cadfa9")}},
} {
tp := reflect.TypeOf(tt.value)
testName := tt.name + ":" + tp.Field(0).Type.String()
val := reflect.New(reflect.TypeOf(tt.value))
val.Elem().Set(reflect.ValueOf(tt.value))
field := val.Elem().Type().Field(0)
_, err := mapping(val, emptyField, formSource{field.Name: {tt.uri}}, "uri")
assert.NoError(t, err, testName)
actual := val.Elem().Field(0).Interface()
assert.Equal(t, tt.expect, actual, testName)
}
}
func TestMappingForm(t *testing.T) { func TestMappingForm(t *testing.T) {
var s struct { var s struct {
F int `form:"field"` F int `form:"field"`

1
go.mod
View File

@ -7,6 +7,7 @@ require (
github.com/gin-contrib/sse v0.1.0 github.com/gin-contrib/sse v0.1.0
github.com/go-playground/validator/v10 v10.11.1 github.com/go-playground/validator/v10 v10.11.1
github.com/goccy/go-json v0.9.11 github.com/goccy/go-json v0.9.11
github.com/google/uuid v1.3.0
github.com/json-iterator/go v1.1.12 github.com/json-iterator/go v1.1.12
github.com/mattn/go-isatty v0.0.16 github.com/mattn/go-isatty v0.0.16
github.com/pelletier/go-toml/v2 v2.0.6 github.com/pelletier/go-toml/v2 v2.0.6

2
go.sum
View File

@ -24,6 +24,8 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=