Skip to content

Commit

Permalink
Add support for the x-order extension.
Browse files Browse the repository at this point in the history
Fix for deepmap#458.
Can be used when you need to set the order of fields in the model:
```yaml
    NewPet:
      type: object
      required:
        - name
      properties:
        name:
          type: string
          x-order: 1
        tag:
          type: string
          x-order: 2
```
  • Loading branch information
psyhatter committed Jun 13, 2022
1 parent 7da811e commit b36f004
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 3 deletions.
53 changes: 50 additions & 3 deletions pkg/codegen/utils.go
Expand Up @@ -14,13 +14,15 @@
package codegen

import (
"encoding/json"
"fmt"
"net/url"
"regexp"
"sort"
"strconv"
"strings"
"unicode"
"unsafe"

"github.com/getkin/kin-openapi/openapi3"
)
Expand Down Expand Up @@ -89,13 +91,58 @@ func ToCamelCase(str string) string {
// This function returns the keys of the given SchemaRef dictionary in sorted
// order, since Golang scrambles dictionary keys
func SortedSchemaKeys(dict map[string]*openapi3.SchemaRef) []string {
keys := make([]string, len(dict))
i := 0
for key := range dict {
var (
i int64
keys = make([]string, len(dict))

needReSorting bool
orders = make(map[string]int64, len(dict))
)

for key, v := range dict {
keys[i] = key
i++

if v == nil {
continue
}

ext := v.Value.Extensions["x-order"]
if ext == nil {
continue
}

var xOrder string
if b, ok := ext.(json.RawMessage); ok {
xOrder = *(*string)(unsafe.Pointer(&b))
} else { // not sure if this is possible.
xOrder = fmt.Sprint(ext)
}

needReSorting = true
order, err := strconv.ParseInt(xOrder, 10, 0)
if err == nil {
orders[key] = order
}
}

sort.Strings(keys)
if !needReSorting {
return keys
}

for i, key := range keys {
if _, exist := orders[key]; !exist {
orders[key] = int64(i)
}
}

sort.Slice(keys, func(i, j int) bool {
if i, j := orders[keys[i]], orders[keys[j]]; i != j {
return i < j
}
return keys[i] < keys[j]
})
return keys
}

Expand Down
26 changes: 26 additions & 0 deletions pkg/codegen/utils_test.go
Expand Up @@ -14,6 +14,8 @@
package codegen

import (
"encoding/json"
"strconv"
"testing"

"github.com/getkin/kin-openapi/openapi3"
Expand Down Expand Up @@ -43,6 +45,30 @@ func TestSortedSchemaKeys(t *testing.T) {
assert.EqualValues(t, expected, SortedSchemaKeys(dict), "Keys are not sorted properly")
}

func TestSortedSchemaKeysWithXOrder(t *testing.T) {
withOrder := func(i int) *openapi3.SchemaRef {
return &openapi3.SchemaRef{
Value: &openapi3.Schema{
ExtensionProps: openapi3.ExtensionProps{
Extensions: map[string]interface{}{"x-order": json.RawMessage(strconv.Itoa(i))},
},
},
}
}
dict := map[string]*openapi3.SchemaRef{
"a": nil,
"c": withOrder(-10),
"b": withOrder(0),
"e": withOrder(-1),
"d": withOrder(1),
"f": withOrder(10),
}

expected := []string{"c", "e", "a", "b", "d", "f"}

assert.EqualValues(t, expected, SortedSchemaKeys(dict), "Keys are not sorted properly")
}

func TestSortedPathsKeys(t *testing.T) {
dict := openapi3.Paths{
"f": nil,
Expand Down

0 comments on commit b36f004

Please sign in to comment.