Skip to content

Commit

Permalink
Merge branch 'main' into client-updates
Browse files Browse the repository at this point in the history
  • Loading branch information
gaby authored Dec 15, 2024
2 parents 3d23da2 + 1134e1f commit e7935da
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 50 deletions.
16 changes: 13 additions & 3 deletions client/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -1020,7 +1020,10 @@ func ReleaseFile(f *File) {
// `p` is a type that implements WithStruct. `tagName` defines the struct tag to look for.
// `v` is the struct containing data.
//
// Only simple types are supported; nested structs are not currently supported.
// Fields in `v` should be string, int, int8, int16, int32, int64, uint,
// uint8, uint16, uint32, uint64, float32, float64, complex64,
// complex128 or bool. Arrays or slices are inserted sequentially with the
// same key. Other types are ignored.
func SetValWithStruct(p WithStruct, tagName string, v any) {
valueOfV := reflect.ValueOf(v)
typeOfV := reflect.TypeOf(v)
Expand All @@ -1039,20 +1042,27 @@ func SetValWithStruct(p WithStruct, tagName string, v any) {
switch val.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
p.Add(name, strconv.Itoa(int(val.Int())))
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
p.Add(name, strconv.FormatUint(val.Uint(), 10))
case reflect.Float32, reflect.Float64:
p.Add(name, strconv.FormatFloat(val.Float(), 'f', -1, 64))
case reflect.Complex64, reflect.Complex128:
p.Add(name, strconv.FormatComplex(val.Complex(), 'f', -1, 128))
case reflect.Bool:
if val.Bool() {
p.Add(name, "true")
} else {
p.Add(name, "false")
}
case reflect.String:
p.Add(name, val.String())
case reflect.Float32, reflect.Float64:
p.Add(name, strconv.FormatFloat(val.Float(), 'f', -1, 64))
case reflect.Slice, reflect.Array:
for i := 0; i < val.Len(); i++ {
setVal(name, val.Index(i))
}
default:
// Unsupported type is ignored.
return
}
}

Expand Down
83 changes: 36 additions & 47 deletions client/request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1530,14 +1530,16 @@ func Test_Request_MaxRedirects(t *testing.T) {
func Test_SetValWithStruct(t *testing.T) {
t.Parallel()

// test SetValWithStruct vai QueryParam struct.
// test SetValWithStruct via QueryParam struct.
type args struct {
TString string
TSlice []string
TIntSlice []int `param:"int_slice"`
unexport int
TInt int
TUint uint
TFloat float64
TComplex complex128
TBool bool
}

Expand All @@ -1550,18 +1552,22 @@ func Test_SetValWithStruct(t *testing.T) {
SetValWithStruct(p, "param", args{
unexport: 5,
TInt: 5,
TUint: 5,
TString: "string",
TFloat: 3.1,
TComplex: 3 + 4i,
TBool: false,
TSlice: []string{"foo", "bar"},
TIntSlice: []int{1, 2},
TIntSlice: []int{0, 1, 2},
})

require.Equal(t, "", string(p.Peek("unexport")))
require.Equal(t, []byte("5"), p.Peek("TInt"))
require.Equal(t, []byte("5"), p.Peek("TUint"))
require.Equal(t, []byte("string"), p.Peek("TString"))
require.Equal(t, []byte("3.1"), p.Peek("TFloat"))
require.Equal(t, "", string(p.Peek("TBool")))
require.Equal(t, []byte("(3+4i)"), p.Peek("TComplex"))
require.Equal(t, []byte("false"), p.Peek("TBool"))
require.True(t, func() bool {
for _, v := range p.PeekMulti("TSlice") {
if string(v) == "foo" {
Expand All @@ -1580,6 +1586,15 @@ func Test_SetValWithStruct(t *testing.T) {
return false
}())

require.True(t, func() bool {
for _, v := range p.PeekMulti("int_slice") {
if string(v) == "0" {
return true
}
}
return false
}())

require.True(t, func() bool {
for _, v := range p.PeekMulti("int_slice") {
if string(v) == "1" {
Expand Down Expand Up @@ -1655,24 +1670,6 @@ func Test_SetValWithStruct(t *testing.T) {
}())
})

t.Run("the zero val should be ignore", func(t *testing.T) {
t.Parallel()
p := &QueryParam{
Args: fasthttp.AcquireArgs(),
}
SetValWithStruct(p, "param", &args{
TInt: 0,
TString: "",
TFloat: 0.0,
})

require.Equal(t, "", string(p.Peek("TInt")))
require.Equal(t, "", string(p.Peek("TString")))
require.Equal(t, "", string(p.Peek("TFloat")))
require.Empty(t, p.PeekMulti("TSlice"))
require.Empty(t, p.PeekMulti("int_slice"))
})

t.Run("error type should ignore", func(t *testing.T) {
t.Parallel()
p := &QueryParam{
Expand All @@ -1684,14 +1681,16 @@ func Test_SetValWithStruct(t *testing.T) {
}

func Benchmark_SetValWithStruct(b *testing.B) {
// test SetValWithStruct vai QueryParam struct.
// test SetValWithStruct via QueryParam struct.
type args struct {
TString string
TSlice []string
TIntSlice []int `param:"int_slice"`
unexport int
TInt int
TUint uint
TFloat float64
TComplex complex128
TBool bool
}

Expand All @@ -1707,19 +1706,23 @@ func Benchmark_SetValWithStruct(b *testing.B) {
SetValWithStruct(p, "param", args{
unexport: 5,
TInt: 5,
TUint: 5,
TString: "string",
TFloat: 3.1,
TComplex: 3 + 4i,
TBool: false,
TSlice: []string{"foo", "bar"},
TIntSlice: []int{1, 2},
TIntSlice: []int{0, 1, 2},
})
}

require.Equal(b, "", string(p.Peek("unexport")))
require.Equal(b, []byte("5"), p.Peek("TInt"))
require.Equal(b, []byte("5"), p.Peek("TUint"))
require.Equal(b, []byte("string"), p.Peek("TString"))
require.Equal(b, []byte("3.1"), p.Peek("TFloat"))
require.Equal(b, "", string(p.Peek("TBool")))
require.Equal(b, []byte("(3+4i)"), p.Peek("TComplex"))
require.Equal(b, []byte("false"), p.Peek("TBool"))
require.True(b, func() bool {
for _, v := range p.PeekMulti("TSlice") {
if string(v) == "foo" {
Expand All @@ -1738,6 +1741,15 @@ func Benchmark_SetValWithStruct(b *testing.B) {
return false
}())

require.True(b, func() bool {
for _, v := range p.PeekMulti("int_slice") {
if string(v) == "0" {
return true
}
}
return false
}())

require.True(b, func() bool {
for _, v := range p.PeekMulti("int_slice") {
if string(v) == "1" {
Expand Down Expand Up @@ -1817,29 +1829,6 @@ func Benchmark_SetValWithStruct(b *testing.B) {
}())
})

b.Run("the zero val should be ignore", func(b *testing.B) {
p := &QueryParam{
Args: fasthttp.AcquireArgs(),
}

b.ReportAllocs()
b.StartTimer()

for i := 0; i < b.N; i++ {
SetValWithStruct(p, "param", &args{
TInt: 0,
TString: "",
TFloat: 0.0,
})
}

require.Empty(b, string(p.Peek("TInt")))
require.Empty(b, string(p.Peek("TString")))
require.Empty(b, string(p.Peek("TFloat")))
require.Empty(b, p.PeekMulti("TSlice"))
require.Empty(b, p.PeekMulti("int_slice"))
})

b.Run("error type should ignore", func(b *testing.B) {
p := &QueryParam{
Args: fasthttp.AcquireArgs(),
Expand Down

0 comments on commit e7935da

Please sign in to comment.