Skip to content

Commit

Permalink
fix and test with queryparams
Browse files Browse the repository at this point in the history
  • Loading branch information
thiagozs committed Oct 30, 2023
1 parent 54254c0 commit 431ff6b
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 10 deletions.
41 changes: 31 additions & 10 deletions structs/structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,30 +24,51 @@ func (s *Structs) ToQueryParams(i any) string {
}

query := url.Values{}
t := v.Type()
for i := 0; i < v.NumField(); i++ {
field := v.Field(i)
fieldType := t.Field(i)
fieldType := v.Type().Field(i)
tag := fieldType.Tag.Get("json")
name := fieldType.Name

// Use JSON tag as field name if it exists, otherwise use struct field name
name := fieldType.Tag.Get("json")
if name == "" {
name = fieldType.Name
// Use JSON tag as field name if it's available
if tag != "" {
name = strings.Split(tag, ",")[0] // Ignore options like omitempty
}

// Convert field name to lower case to follow common query parameter naming conventions
name = strings.ToLower(name)
// Skip zero values for fields with omitempty
if strings.Contains(tag, "omitempty") && isEmptyValue(field) {
continue
}

switch field.Kind() {
case reflect.Slice:
var sliceValues []string
for j := 0; j < field.Len(); j++ {
sliceValues = append(sliceValues, fmt.Sprintf("%v", field.Index(j)))
}
query.Add(name, strings.Join(sliceValues, ","))
query.Add(strings.ToLower(name), strings.Join(sliceValues, ","))
default:
query.Add(name, fmt.Sprintf("%v", field.Interface()))
query.Add(strings.ToLower(name), fmt.Sprintf("%v", field.Interface()))
}
}
return query.Encode()
}

// isEmptyValue checks if a reflect.Value is considered empty
func isEmptyValue(v reflect.Value) bool {
switch v.Kind() {
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
return v.Len() == 0
case reflect.Bool:
return !v.Bool()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return v.Int() == 0
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return v.Uint() == 0
case reflect.Float32, reflect.Float64:
return v.Float() == 0
case reflect.Interface, reflect.Ptr:
return v.IsNil()
}
return false
}
32 changes: 32 additions & 0 deletions structs/structs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,35 @@ func TestToQueryParamsWithJSONtags(t *testing.T) {
})
}
}

func TestToQueryParamsWithJSONtagsomitempty(t *testing.T) {
s := New()

tests := []struct {
name string
input any
expected string
}{
{
name: "Test with omitempty",
input: struct {
Name string `json:"name,omitempty"`
Age int `json:"age,omitempty"`
Email string `json:"email,omitempty"`
}{
Name: "John Doe",
Email: "[email protected]",
},
expected: "email=john.doe%40example.com&name=John+Doe",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := s.ToQueryParams(tt.input)
if result != tt.expected {
t.Errorf("Expected %s, got %s", tt.expected, result)
}
})
}
}

0 comments on commit 431ff6b

Please sign in to comment.