Skip to content

Commit d4b9b85

Browse files
authored
Support param styling for UUIDs (#643)
Previously attempting to style a param would result in the error message: unsupported type uuid.UUID This follows the same pattern as supporting time.Time and types.Date to now support types.UUID.
1 parent 51d47be commit d4b9b85

2 files changed

Lines changed: 120 additions & 8 deletions

File tree

styleparam.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,9 @@ func sortedKeys(strMap map[string]string) []string {
158158
return keys
159159
}
160160

161-
// This is a special case. The struct may be a date or time, in
162-
// which case, marshal it in correct format.
163-
func marshalDateTimeValue(value interface{}) (string, bool) {
161+
// These are special cases. The value may be a date, time, or uuid,
162+
// in which case, marshal it into the correct format.
163+
func marshalKnownTypes(value interface{}) (string, bool) {
164164
v := reflect.Indirect(reflect.ValueOf(value))
165165
t := v.Type()
166166

@@ -176,12 +176,17 @@ func marshalDateTimeValue(value interface{}) (string, bool) {
176176
return dateVal.Format(types.DateFormat), true
177177
}
178178

179+
if t.ConvertibleTo(reflect.TypeOf(types.UUID{})) {
180+
u := v.Convert(reflect.TypeOf(types.UUID{}))
181+
uuidVal := u.Interface().(types.UUID)
182+
return uuidVal.String(), true
183+
}
184+
179185
return "", false
180186
}
181187

182188
func styleStruct(style string, explode bool, paramName string, paramLocation ParamLocation, value interface{}) (string, error) {
183-
184-
if timeVal, ok := marshalDateTimeValue(value); ok {
189+
if timeVal, ok := marshalKnownTypes(value); ok {
185190
styledVal, err := stylePrimitive(style, explode, paramName, paramLocation, timeVal)
186191
if err != nil {
187192
return "", fmt.Errorf("failed to style time: %w", err)
@@ -350,7 +355,7 @@ func primitiveToString(value interface{}) (string, error) {
350355

351356
// sometimes time and date used like primitive types
352357
// it can happen if paramether is object and has time or date as field
353-
if res, ok := marshalDateTimeValue(value); ok {
358+
if res, ok := marshalKnownTypes(value); ok {
354359
return res, nil
355360
}
356361

styleparam_test.go

Lines changed: 109 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"testing"
1818
"time"
1919

20+
"github.com/google/uuid"
2021
"github.com/stretchr/testify/assert"
2122

2223
"github.com/deepmap/oapi-codegen/pkg/types"
@@ -46,6 +47,9 @@ func TestStyleParam(t *testing.T) {
4647
type AliasedDate types.Date
4748
date := AliasedDate{time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)}
4849

50+
type AliasedUUID types.UUID
51+
aUUID := AliasedUUID(uuid.MustParse("baa07328-452e-40bd-aa2e-fa823ec13605"))
52+
4953
// ---------------------------- Simple Style -------------------------------
5054

5155
result, err := StyleParamWithLocation("simple", false, "id", ParamLocationQuery, primitive)
@@ -112,6 +116,22 @@ func TestStyleParam(t *testing.T) {
112116
assert.NoError(t, err)
113117
assert.EqualValues(t, "2020-01-01", result)
114118

119+
result, err = StyleParamWithLocation("simple", false, "id", ParamLocationQuery, aUUID)
120+
assert.NoError(t, err)
121+
assert.EqualValues(t, "baa07328-452e-40bd-aa2e-fa823ec13605", result)
122+
123+
result, err = StyleParamWithLocation("simple", true, "id", ParamLocationQuery, aUUID)
124+
assert.NoError(t, err)
125+
assert.EqualValues(t, "baa07328-452e-40bd-aa2e-fa823ec13605", result)
126+
127+
result, err = StyleParamWithLocation("simple", false, "id", ParamLocationQuery, &aUUID)
128+
assert.NoError(t, err)
129+
assert.EqualValues(t, "baa07328-452e-40bd-aa2e-fa823ec13605", result)
130+
131+
result, err = StyleParamWithLocation("simple", true, "id", ParamLocationQuery, &aUUID)
132+
assert.NoError(t, err)
133+
assert.EqualValues(t, "baa07328-452e-40bd-aa2e-fa823ec13605", result)
134+
115135
// ----------------------------- Label Style -------------------------------
116136

117137
result, err = StyleParamWithLocation("label", false, "id", ParamLocationQuery, primitive)
@@ -178,6 +198,22 @@ func TestStyleParam(t *testing.T) {
178198
assert.NoError(t, err)
179199
assert.EqualValues(t, ".2020-01-01", result)
180200

201+
result, err = StyleParamWithLocation("label", false, "id", ParamLocationQuery, aUUID)
202+
assert.NoError(t, err)
203+
assert.EqualValues(t, ".baa07328-452e-40bd-aa2e-fa823ec13605", result)
204+
205+
result, err = StyleParamWithLocation("label", true, "id", ParamLocationQuery, aUUID)
206+
assert.NoError(t, err)
207+
assert.EqualValues(t, ".baa07328-452e-40bd-aa2e-fa823ec13605", result)
208+
209+
result, err = StyleParamWithLocation("label", false, "id", ParamLocationQuery, &aUUID)
210+
assert.NoError(t, err)
211+
assert.EqualValues(t, ".baa07328-452e-40bd-aa2e-fa823ec13605", result)
212+
213+
result, err = StyleParamWithLocation("label", true, "id", ParamLocationQuery, &aUUID)
214+
assert.NoError(t, err)
215+
assert.EqualValues(t, ".baa07328-452e-40bd-aa2e-fa823ec13605", result)
216+
181217
// ----------------------------- Matrix Style ------------------------------
182218

183219
result, err = StyleParamWithLocation("matrix", false, "id", ParamLocationQuery, primitive)
@@ -244,6 +280,22 @@ func TestStyleParam(t *testing.T) {
244280
assert.NoError(t, err)
245281
assert.EqualValues(t, ";id=2020-01-01", result)
246282

283+
result, err = StyleParamWithLocation("matrix", false, "id", ParamLocationQuery, aUUID)
284+
assert.NoError(t, err)
285+
assert.EqualValues(t, ";id=baa07328-452e-40bd-aa2e-fa823ec13605", result)
286+
287+
result, err = StyleParamWithLocation("matrix", true, "id", ParamLocationQuery, aUUID)
288+
assert.NoError(t, err)
289+
assert.EqualValues(t, ";id=baa07328-452e-40bd-aa2e-fa823ec13605", result)
290+
291+
result, err = StyleParamWithLocation("matrix", false, "id", ParamLocationQuery, &aUUID)
292+
assert.NoError(t, err)
293+
assert.EqualValues(t, ";id=baa07328-452e-40bd-aa2e-fa823ec13605", result)
294+
295+
result, err = StyleParamWithLocation("matrix", true, "id", ParamLocationQuery, &aUUID)
296+
assert.NoError(t, err)
297+
assert.EqualValues(t, ";id=baa07328-452e-40bd-aa2e-fa823ec13605", result)
298+
247299
// ------------------------------ Form Style -------------------------------
248300
result, err = StyleParamWithLocation("form", false, "id", ParamLocationQuery, primitive)
249301
assert.NoError(t, err)
@@ -325,6 +377,22 @@ func TestStyleParam(t *testing.T) {
325377
assert.NoError(t, err)
326378
assert.EqualValues(t, "id=2020-01-01", result)
327379

380+
result, err = StyleParamWithLocation("form", false, "id", ParamLocationQuery, aUUID)
381+
assert.NoError(t, err)
382+
assert.EqualValues(t, "id=baa07328-452e-40bd-aa2e-fa823ec13605", result)
383+
384+
result, err = StyleParamWithLocation("form", true, "id", ParamLocationQuery, aUUID)
385+
assert.NoError(t, err)
386+
assert.EqualValues(t, "id=baa07328-452e-40bd-aa2e-fa823ec13605", result)
387+
388+
result, err = StyleParamWithLocation("form", false, "id", ParamLocationQuery, &aUUID)
389+
assert.NoError(t, err)
390+
assert.EqualValues(t, "id=baa07328-452e-40bd-aa2e-fa823ec13605", result)
391+
392+
result, err = StyleParamWithLocation("form", true, "id", ParamLocationQuery, &aUUID)
393+
assert.NoError(t, err)
394+
assert.EqualValues(t, "id=baa07328-452e-40bd-aa2e-fa823ec13605", result)
395+
328396
// ------------------------ spaceDelimited Style --------------------------
329397

330398
result, err = StyleParamWithLocation("spaceDelimited", false, "id", ParamLocationQuery, primitive)
@@ -377,6 +445,18 @@ func TestStyleParam(t *testing.T) {
377445
result, err = StyleParamWithLocation("spaceDelimited", true, "id", ParamLocationQuery, &date)
378446
assert.Error(t, err)
379447

448+
result, err = StyleParamWithLocation("spaceDelimited", false, "id", ParamLocationQuery, aUUID)
449+
assert.Error(t, err)
450+
451+
result, err = StyleParamWithLocation("spaceDelimited", true, "id", ParamLocationQuery, aUUID)
452+
assert.Error(t, err)
453+
454+
result, err = StyleParamWithLocation("spaceDelimited", false, "id", ParamLocationQuery, &aUUID)
455+
assert.Error(t, err)
456+
457+
result, err = StyleParamWithLocation("spaceDelimited", true, "id", ParamLocationQuery, &aUUID)
458+
assert.Error(t, err)
459+
380460
// ------------------------- pipeDelimited Style --------------------------
381461

382462
result, err = StyleParamWithLocation("pipeDelimited", false, "id", ParamLocationQuery, primitive)
@@ -429,6 +509,18 @@ func TestStyleParam(t *testing.T) {
429509
result, err = StyleParamWithLocation("pipeDelimited", true, "id", ParamLocationQuery, &date)
430510
assert.Error(t, err)
431511

512+
result, err = StyleParamWithLocation("pipeDelimited", false, "id", ParamLocationQuery, aUUID)
513+
assert.Error(t, err)
514+
515+
result, err = StyleParamWithLocation("pipeDelimited", true, "id", ParamLocationQuery, aUUID)
516+
assert.Error(t, err)
517+
518+
result, err = StyleParamWithLocation("pipeDelimited", false, "id", ParamLocationQuery, &aUUID)
519+
assert.Error(t, err)
520+
521+
result, err = StyleParamWithLocation("pipeDelimited", true, "id", ParamLocationQuery, &aUUID)
522+
assert.Error(t, err)
523+
432524
// --------------------------- deepObject Style ---------------------------
433525
result, err = StyleParamWithLocation("deepObject", false, "id", ParamLocationQuery, primitive)
434526
assert.Error(t, err)
@@ -478,6 +570,18 @@ func TestStyleParam(t *testing.T) {
478570
result, err = StyleParamWithLocation("deepObject", true, "id", ParamLocationQuery, &date)
479571
assert.Error(t, err)
480572

573+
result, err = StyleParamWithLocation("deepObject", false, "id", ParamLocationQuery, aUUID)
574+
assert.Error(t, err)
575+
576+
result, err = StyleParamWithLocation("deepObject", true, "id", ParamLocationQuery, aUUID)
577+
assert.Error(t, err)
578+
579+
result, err = StyleParamWithLocation("deepObject", false, "id", ParamLocationQuery, &aUUID)
580+
assert.Error(t, err)
581+
582+
result, err = StyleParamWithLocation("deepObject", true, "id", ParamLocationQuery, &aUUID)
583+
assert.Error(t, err)
584+
481585
// Misc tests
482586
// Test type aliases
483587
type StrType string
@@ -546,22 +650,25 @@ func TestStyleParam(t *testing.T) {
546650
assert.NoError(t, err)
547651
assert.EqualValues(t, "firstName,Alex", result)
548652

549-
// Test handling of time and date inside objects
653+
// Test handling of other known types inside objects
550654
type testObject3 struct {
551655
TimeField time.Time `json:"time_field"`
552656
DateField types.Date `json:"date_field"`
657+
UUIDField types.UUID `json:"uuid_field"`
553658
}
554659
timeVal := time.Date(1996, time.March, 19, 0, 0, 0, 0, time.UTC)
555660
dateVal := types.Date{
556661
Time: timeVal,
557662
}
663+
uuidVal := uuid.MustParse("baa07328-452e-40bd-aa2e-fa823ec13605")
558664

559665
object3 := testObject3{
560666
TimeField: timeVal,
561667
DateField: dateVal,
668+
UUIDField: uuid.UUID(uuidVal),
562669
}
563670

564671
result, err = StyleParamWithLocation("simple", false, "id", ParamLocationQuery, object3)
565672
assert.NoError(t, err)
566-
assert.EqualValues(t, "date_field,1996-03-19,time_field,1996-03-19T00%3A00%3A00Z", result)
673+
assert.EqualValues(t, "date_field,1996-03-19,time_field,1996-03-19T00%3A00%3A00Z,uuid_field,baa07328-452e-40bd-aa2e-fa823ec13605", result)
567674
}

0 commit comments

Comments
 (0)