1
0
mirror of https://github.com/duke-git/lancet.git synced 2026-02-04 12:52:28 +08:00

Add StructUtil for provide more rich functions (#79)

* add support json tag attribute for StructToMap function

* add the structutil to provide more rich functions and fixed #77
This commit is contained in:
zm
2023-03-13 19:28:37 +08:00
committed by GitHub
parent 1755dd249b
commit 924589d2da
9 changed files with 263 additions and 64 deletions

View File

@@ -21,12 +21,11 @@ import (
"io"
"net/http"
"net/url"
"reflect"
"regexp"
"sort"
"strings"
"time"
"github.com/duke-git/lancet/v2/convertor"
"github.com/duke-git/lancet/v2/slice"
)
@@ -219,7 +218,7 @@ func (client *HttpClient) setTLS(rawUrl string) {
}
}
// setHeader set http rquest header
// setHeader set http request header
func (client *HttpClient) setHeader(req *http.Request, headers http.Header) {
if headers == nil {
headers = make(http.Header)
@@ -278,29 +277,15 @@ func validateRequest(req *HttpRequest) error {
// StructToUrlValues convert struct to url valuse,
// only convert the field which is exported and has `json` tag.
// Play: https://go.dev/play/p/pFqMkM40w9z
func StructToUrlValues(targetStruct any) url.Values {
rv := reflect.ValueOf(targetStruct)
rt := reflect.TypeOf(targetStruct)
if rt.Kind() == reflect.Ptr {
rt = rt.Elem()
}
if rt.Kind() != reflect.Struct {
panic(fmt.Errorf("data type %T not support, shuld be struct or pointer to struct", targetStruct))
}
func StructToUrlValues(targetStruct any) (url.Values, error) {
result := url.Values{}
fieldNum := rt.NumField()
pattern := `^[A-Z]`
regex := regexp.MustCompile(pattern)
for i := 0; i < fieldNum; i++ {
name := rt.Field(i).Name
tag := rt.Field(i).Tag.Get("json")
if regex.MatchString(name) && tag != "" {
result.Add(tag, fmt.Sprintf("%v", rv.Field(i).Interface()))
}
s, err := convertor.StructToMap(targetStruct)
if err != nil {
return nil, err
}
for k, v := range s {
result.Add(k, fmt.Sprintf("%v", v))
}
return result
return result, nil
}

View File

@@ -217,17 +217,22 @@ func TestStructToUrlValues(t *testing.T) {
assert := internal.NewAssert(t, "TestStructToUrlValues")
type TodoQuery struct {
Id int `json:"id"`
UserId int `json:"userId"`
Id int `json:"id"`
UserId int `json:"userId"`
Name string `json:"name,omitempty"`
}
todoQuery := TodoQuery{
Id: 1,
UserId: 1,
}
todoValues := StructToUrlValues(todoQuery)
todoValues, err := StructToUrlValues(todoQuery)
if err != nil {
t.Errorf("params is invalid: %v", err)
}
assert.Equal("1", todoValues.Get("id"))
assert.Equal("1", todoValues.Get("userId"))
assert.Equal("", todoValues.Get("name"))
request := &HttpRequest{
RawURL: "https://jsonplaceholder.typicode.com/todos",

View File

@@ -123,14 +123,17 @@ func ExampleHttpClient_DecodeResponse() {
func ExampleStructToUrlValues() {
type TodoQuery struct {
Id int `json:"id"`
Id int `json:"id,omitempty"`
Name string `json:"name"`
}
todoQuery := TodoQuery{
Id: 1,
Name: "Test",
}
todoValues := StructToUrlValues(todoQuery)
todoValues, err := StructToUrlValues(todoQuery)
if err != nil {
return
}
fmt.Println(todoValues.Get("id"))
fmt.Println(todoValues.Get("name"))