queryparams: Handle pointer fields in structs

This commit is contained in:
kargakis 2015-09-02 18:24:47 +02:00
parent 77e2d4f918
commit edfaa480cf
2 changed files with 40 additions and 4 deletions

View File

@ -50,6 +50,10 @@ func formatValue(value interface{}) string {
return fmt.Sprintf("%v", value)
}
func isPointerKind(kind reflect.Kind) bool {
return kind == reflect.Ptr
}
func isValueKind(kind reflect.Kind) bool {
switch kind {
case reflect.String, reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16,
@ -92,11 +96,11 @@ func Convert(obj runtime.Object) (url.Values, error) {
case reflect.Ptr, reflect.Interface:
sv = reflect.ValueOf(obj).Elem()
default:
return nil, fmt.Errorf("Expecting a pointer or interface")
return nil, fmt.Errorf("expecting a pointer or interface")
}
st := sv.Type()
if st.Kind() != reflect.Struct {
return nil, fmt.Errorf("Expecting a pointer to a struct")
return nil, fmt.Errorf("expecting a pointer to a struct")
}
for i := 0; i < st.NumField(); i++ {
field := sv.Field(i)
@ -105,10 +109,18 @@ func Convert(obj runtime.Object) (url.Values, error) {
continue
}
ft := field.Type()
kind := ft.Kind()
if isPointerKind(kind) {
kind = ft.Elem().Kind()
if !field.IsNil() {
field = reflect.Indirect(field)
}
}
switch {
case isValueKind(ft.Kind()):
case isValueKind(kind):
addParam(result, tag, omitempty, field)
case ft.Kind() == reflect.Array || ft.Kind() == reflect.Slice:
case kind == reflect.Array || kind == reflect.Slice:
if isValueKind(ft.Elem().Kind()) {
addListOfParams(result, tag, omitempty, field)
}

View File

@ -53,6 +53,13 @@ type foo struct {
func (*foo) IsAnAPIObject() {}
type baz struct {
Ptr *int `json:"ptr"`
Bptr *bool `json:"bptr,omitempty"`
}
func (*baz) IsAnAPIObject() {}
func validateResult(t *testing.T, input interface{}, actual, expected url.Values) {
local := url.Values{}
for k, v := range expected {
@ -131,6 +138,19 @@ func TestConvert(t *testing.T) {
},
expected: url.Values{"str": {""}, "namedStr": {"named str"}},
},
{
input: &baz{
Ptr: intp(5),
Bptr: boolp(true),
},
expected: url.Values{"ptr": {"5"}, "bptr": {"true"}},
},
{
input: &baz{
Bptr: boolp(true),
},
expected: url.Values{"ptr": {"<nil>"}, "bptr": {"true"}},
},
}
for _, test := range tests {
@ -141,3 +161,7 @@ func TestConvert(t *testing.T) {
validateResult(t, test.input, result, test.expected)
}
}
func intp(n int) *int { return &n }
func boolp(b bool) *bool { return &b }