From 067c168887368685c9e3ca8324184153d413e167 Mon Sep 17 00:00:00 2001 From: Ido Perlmuter Date: Tue, 1 Sep 2020 17:47:59 +0300 Subject: [PATCH] Support optional boolean query parameters (i.e. pointers) This commit adds support for boolean query parameters that are optional, meaning their type is `*bool` rather than `bool`. This is useful in cases where an API must know whether the parameter was actually provided, even if it was false, and not just received a zero value. --- decoder.go | 7 +++++++ decoder_test.go | 6 ++++++ structs_test.go | 3 +++ 3 files changed, 16 insertions(+) diff --git a/decoder.go b/decoder.go index d857a8f..dd1bd34 100644 --- a/decoder.go +++ b/decoder.go @@ -174,6 +174,13 @@ func unmarshalField( valueField.SetFloat(value) case reflect.Bool: valueField.SetBool(boolRegex.MatchString(strings.ToLower(params[param]))) + case reflect.Ptr: + if typeField.Elem().Kind() == reflect.Bool { + if val, ok := params[param]; ok { + b := boolRegex.MatchString(strings.ToLower(val)) + valueField.Set(reflect.ValueOf(&b)) + } + } case reflect.Slice: // we'll be extracting values from multiParam, generating a slice and // putting it in valueField diff --git a/decoder_test.go b/decoder_test.go index c9df8e6..1c9ee82 100644 --- a/decoder_test.go +++ b/decoder_test.go @@ -22,6 +22,8 @@ func Test_UnmarshalRequest(t *testing.T) { "page": "2", "page_size": "30", "const": "two", + "bool": "true", + "pbool1": "0", }, MultiValueQueryStringParameters: map[string][]string{ "terms": []string{"one", "two"}, @@ -43,6 +45,10 @@ func Test_UnmarshalRequest(t *testing.T) { assert.Equal(t, int64(30), input.PageSize, "PageSize must be parsed from query") assert.Equal(t, "en-us", input.Language, "Language must be parsed from headers") assert.Equal(t, mockConstTwo, input.Const, "Const must be parsed from query") + assert.True(t, input.Bool, "Bool must be true") + assert.NotNil(t, input.PBoolOne, "PBoolOne must not be nil") + assert.False(t, *input.PBoolOne, "PBoolOne must be *false") + assert.Equal(t, (*bool)(nil), input.PBoolTwo, "PBoolTwo must be nil") assert.DeepEqual(t, []string{"one", "two"}, input.Terms, "Terms must be parsed from multiple query params") assert.DeepEqual(t, []float64{1.2, 3.5, 666.666}, input.Numbers, "Numbers must be parsed from multiple query params") assert.DeepEqual(t, []string{"gzip", "deflate"}, input.Encoding, "Encoding must be parsed from multiple header params") diff --git a/structs_test.go b/structs_test.go index fbe7c1a..e244a8e 100644 --- a/structs_test.go +++ b/structs_test.go @@ -16,6 +16,9 @@ type mockListRequest struct { Terms []string `lambda:"query.terms"` Numbers []float64 `lambda:"query.numbers"` Const mockConst `lambda:"query.const"` + Bool bool `lambda:"query.bool"` + PBoolOne *bool `lambda:"query.pbool1"` + PBoolTwo *bool `lambda:"query.pbool2"` Language string `lambda:"header.Accept-Language"` Encoding []string `lambda:"header.Accept-Encoding"` }