Skip to content

Commit

Permalink
client: add support for go1.23 iterators
Browse files Browse the repository at this point in the history
  • Loading branch information
efectn committed Dec 2, 2024
1 parent 0949f42 commit 7578ae3
Show file tree
Hide file tree
Showing 4 changed files with 440 additions and 0 deletions.
131 changes: 131 additions & 0 deletions client/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ import (
"context"
"errors"
"io"
"iter"
"path/filepath"
"reflect"
"slices"
"strconv"
"sync"
"time"
Expand Down Expand Up @@ -129,6 +131,29 @@ func (r *Request) Header(key string) []string {
return r.header.PeekMultiple(key)
}

// Headers returns all headers in the request using an iterator.
// You can use maps.Collect() to collect all headers into a map.
//
// The returned value is valid until the request object is released.
// Any future calls to Headers method will return the modified value. Do not store references to returned value. Make copies instead.
func (r *Request) Headers() iter.Seq2[string, []string] {
return func(yield func(string, []string) bool) {
keys := r.header.PeekKeys()

for _, key := range keys {
vals := r.header.PeekAll(utils.UnsafeString(key))
valsStr := make([]string, len(vals))
for i, v := range vals {
valsStr[i] = utils.UnsafeString(v)
}

if !yield(utils.UnsafeString(key), valsStr) {
return
}
}
}
}

// AddHeader method adds a single header field and its value in the request instance.
func (r *Request) AddHeader(key, val string) *Request {
r.header.Add(key, val)
Expand Down Expand Up @@ -168,6 +193,33 @@ func (r *Request) Param(key string) []string {
return res
}

// Params returns all params in the request using an iterator.
// You can use maps.Collect() to collect all params into a map.
//
// The returned value is valid until the request object is released.
// Any future calls to Params method will return the modified value. Do not store references to returned value. Make copies instead.
func (r *Request) Params() iter.Seq2[string, []string] {
return func(yield func(string, []string) bool) {
keys := r.params.Keys()

for _, key := range keys {
if key == "" {
continue
}

vals := r.params.PeekMulti(key)
valsStr := make([]string, len(vals))
for i, v := range vals {
valsStr[i] = utils.UnsafeString(v)
}

if !yield(key, valsStr) {
return
}
}
}
}

// AddParam method adds a single param field and its value in the request instance.
func (r *Request) AddParam(key, val string) *Request {
r.params.Add(key, val)
Expand Down Expand Up @@ -254,6 +306,18 @@ func (r *Request) Cookie(key string) string {
return ""
}

// Cookies returns all cookies in the cookies using an iterator.
// You can use maps.Collect() to collect all cookies into a map.
func (r *Request) Cookies() iter.Seq2[string, string] {
return func(yield func(string, string) bool) {
r.cookies.VisitAll(func(key, val string) {
if !yield(key, val) {
return
}
})
}
}

// SetCookie method sets a single cookie field and its value in the request instance.
// It will override cookie which set in client instance.
func (r *Request) SetCookie(key, val string) *Request {
Expand Down Expand Up @@ -291,6 +355,18 @@ func (r *Request) PathParam(key string) string {
return ""
}

// PathParams returns all path params in request instance.
// You can use maps.Collect() to collect all cookies into a map.
func (r *Request) PathParams() iter.Seq2[string, string] {
return func(yield func(string, string) bool) {
r.path.VisitAll(func(key, val string) {
if !yield(key, val) {
return
}
})
}
}

// SetPathParam method sets a single path param field and its value in the request instance.
// It will override path param which set in client instance.
func (r *Request) SetPathParam(key, val string) *Request {
Expand Down Expand Up @@ -376,6 +452,33 @@ func (r *Request) FormData(key string) []string {
return res
}

// FormDatas method returns all form datas in request instance.
// You can use maps.Collect() to collect all cookies into a map.
//
// The returned value is valid until the request object is released.
// Any future calls to FormDatas method will return the modified value. Do not store references to returned value. Make copies instead.
func (r *Request) FormDatas() iter.Seq2[string, []string] {
return func(yield func(string, []string) bool) {
keys := r.formData.Keys()

for _, key := range keys {
if key == "" {
continue
}

vals := r.formData.PeekMulti(key)
valsStr := make([]string, len(vals))
for i, v := range vals {
valsStr[i] = utils.UnsafeString(v)
}

if !yield(key, valsStr) {
return
}
}
}
}

// AddFormData method adds a single form data field and its value in the request instance.
func (r *Request) AddFormData(key, val string) *Request {
r.formData.AddData(key, val)
Expand Down Expand Up @@ -435,6 +538,14 @@ func (r *Request) File(name string) *File {
return nil
}

// Files method returns all files in request instance.
//
// The returned value is valid until the request object is released.
// Any future calls to Files method will return the modified value. Do not store references to returned value. Make copies instead.
func (r *Request) Files() []*File {
return r.files
}

// FileByPath returns file ptr store in request obj by path.
func (r *Request) FileByPath(path string) *File {
for _, v := range r.files {
Expand Down Expand Up @@ -617,6 +728,16 @@ type QueryParam struct {
*fasthttp.Args
}

// Keys method returns all keys in the query params.
func (f *QueryParam) Keys() []string {
keys := make([]string, f.Len())
f.VisitAll(func(key, value []byte) {

Check failure on line 734 in client/request.go

View workflow job for this annotation

GitHub Actions / lint

unused-parameter: parameter 'value' seems to be unused, consider removing or renaming it as _ (revive)
keys = append(keys, utils.UnsafeString(key))

Check failure on line 735 in client/request.go

View workflow job for this annotation

GitHub Actions / lint

append to slice `keys` with non-zero initialized length (makezero)
})

return slices.Compact(keys)
}

// AddParams receive a map and add each value to param.
func (p *QueryParam) AddParams(r map[string][]string) {

Check failure on line 742 in client/request.go

View workflow job for this annotation

GitHub Actions / lint

receiver-naming: receiver name p should be consistent with previous receiver name f for QueryParam (revive)

Check failure on line 742 in client/request.go

View workflow job for this annotation

GitHub Actions / lint

ST1016: methods on the same type should have the same receiver name (seen 1x "f", 3x "p") (stylecheck)
for k, v := range r {
Expand Down Expand Up @@ -747,6 +868,16 @@ type FormData struct {
*fasthttp.Args
}

// Keys method returns all keys in the form data.
func (f *FormData) Keys() []string {
keys := make([]string, f.Len())
f.VisitAll(func(key, value []byte) {

Check failure on line 874 in client/request.go

View workflow job for this annotation

GitHub Actions / lint

unused-parameter: parameter 'value' seems to be unused, consider removing or renaming it as _ (revive)
keys = append(keys, utils.UnsafeString(key))

Check failure on line 875 in client/request.go

View workflow job for this annotation

GitHub Actions / lint

append to slice `keys` with non-zero initialized length (makezero)
})

return slices.Compact(keys)
}

// AddData method is a wrapper of Args's Add method.
func (f *FormData) AddData(key, val string) {
f.Add(key, val)
Expand Down
Loading

0 comments on commit 7578ae3

Please sign in to comment.