Skip to content

Commit

Permalink
Fix breaking changes recently committed (#20)
Browse files Browse the repository at this point in the history
Pull request #19 introduced
an extra parameter into a widely used function, which would break existing
generated code with the next release.

Restore the previous function to its old signature, and add a new one
which takes additional options in an options structure.

Co-authored-by: marcinromaszewicz <[email protected]>
  • Loading branch information
deepmap-marcinr and marcinromaszewicz authored Nov 14, 2023
1 parent 7290e8f commit 53c0dbc
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 11 deletions.
6 changes: 5 additions & 1 deletion bindform.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,11 @@ func BindForm(ptr interface{}, form map[string][]string, files map[string][]*mul
if encoding.Required != nil {
required = *encoding.Required
}
if err := BindStyledParameterWithLocation(encoding.Style, explode, required, tag, ParamLocationUndefined, value, field.Addr().Interface()); err != nil {
if err := BindStyledParameterWithOptions(encoding.Style, tag, value, field.Addr().Interface(), BindStyledParameterOptions{
ParamLocation: ParamLocationUndefined,
Explode: explode,
Required: required,
}); err != nil {
return err
}
}
Expand Down
43 changes: 35 additions & 8 deletions bindparam.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,26 +31,53 @@ import (
// https://swagger.io/docs/specification/serialization/
// It is a backward compatible function to clients generated with codegen
// up to version v1.5.5. v1.5.6+ calls the function below.
func BindStyledParameter(style string, explode bool, required bool, paramName string,
// Deprecated: BindStyledParameter is deprecated.
func BindStyledParameter(style string, explode bool, paramName string,
value string, dest interface{}) error {
return BindStyledParameterWithLocation(style, explode, required, paramName, ParamLocationUndefined, value, dest)
return BindStyledParameterWithOptions(style, paramName, value, dest, BindStyledParameterOptions{
ParamLocation: ParamLocationUndefined,
Explode: explode,
Required: true,
})
}

// BindStyledParameterWithLocation binds a parameter as described in the Path Parameters
// section here to a Go object:
// https://swagger.io/docs/specification/serialization/
func BindStyledParameterWithLocation(style string, explode bool, required bool, paramName string,
// This is a compatibility function which is used by oapi-codegen v2.0.0 and earlier.
// Deprecated: BindStyledParameterWithLocation is deprecated.
func BindStyledParameterWithLocation(style string, explode bool, paramName string,
paramLocation ParamLocation, value string, dest interface{}) error {
return BindStyledParameterWithOptions(style, paramName, value, dest, BindStyledParameterOptions{
ParamLocation: paramLocation,
Explode: explode,
Required: true, // This emulates behavior before the required parameter was optional.
})
}

if required {
// BindStyledParameterOptions defines optional arguments for BindStyledParameterWithOptions
type BindStyledParameterOptions struct {
// ParamLocation tells us where the parameter is located in the request.
ParamLocation ParamLocation
// Whether the parameter should use exploded structure
Explode bool
// Whether the parameter is required in the query
Required bool
}

// BindStyledParameterWithOptions binds a parameter as described in the Path Parameters
// section here to a Go object:
// https://swagger.io/docs/specification/serialization/
func BindStyledParameterWithOptions(style string, paramName string, value string, dest any, opts BindStyledParameterOptions) error {
if opts.Required {
if value == "" {
return fmt.Errorf("parameter '%s' is empty, can't bind its value", paramName)
}
}

// Based on the location of the parameter, we need to unescape it properly.
var err error
switch paramLocation {
switch opts.ParamLocation {
case ParamLocationQuery, ParamLocationUndefined:
// We unescape undefined parameter locations here for older generated code,
// since prior to this refactoring, they always query unescaped.
Expand Down Expand Up @@ -85,17 +112,17 @@ func BindStyledParameterWithLocation(style string, explode bool, required bool,
if t.Kind() == reflect.Struct {
// We've got a destination object, we'll create a JSON representation
// of the input value, and let the json library deal with the unmarshaling
parts, err := splitStyledParameter(style, explode, true, paramName, value)
parts, err := splitStyledParameter(style, opts.Explode, true, paramName, value)
if err != nil {
return err
}

return bindSplitPartsToDestinationStruct(paramName, parts, explode, dest)
return bindSplitPartsToDestinationStruct(paramName, parts, opts.Explode, dest)
}

if t.Kind() == reflect.Slice {
// Chop up the parameter into parts based on its style
parts, err := splitStyledParameter(style, explode, false, paramName, value)
parts, err := splitStyledParameter(style, opts.Explode, false, paramName, value)
if err != nil {
return fmt.Errorf("error splitting input '%s' into parts: %s", value, err)
}
Expand Down
8 changes: 6 additions & 2 deletions bindparam_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -493,8 +493,12 @@ func TestBindStyledParameterWithLocation(t *testing.T) {
expectedBig := big.NewInt(12345678910)

var dstBigNumber big.Int
err := BindStyledParameterWithLocation("simple", false, false, "id", ParamLocationUndefined,
"12345678910", &dstBigNumber)

err := BindStyledParameterWithOptions("simple", "id", "12345678910", &dstBigNumber, BindStyledParameterOptions{
ParamLocation: ParamLocationUndefined,
Explode: false,
Required: false,
})
assert.NoError(t, err)
assert.Equal(t, *expectedBig, dstBigNumber)
}

0 comments on commit 53c0dbc

Please sign in to comment.