Skip to content

Commit 0fedbbd

Browse files
committed
Use ordered maps
Signed-off-by: Pierre Fenoll <[email protected]>
1 parent 2ed340d commit 0fedbbd

35 files changed

+521
-281
lines changed

.github/workflows/go.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
strategy:
1313
fail-fast: true
1414
matrix:
15-
go: ['1.16', '1.x']
15+
go: ['1.x']
1616
os:
1717
- ubuntu-latest
1818
- windows-latest
@@ -93,7 +93,7 @@ jobs:
9393
run: |
9494
! git grep -InE 'json:"' | grep -v _test.go | grep -v yaml:
9595
96-
- if: runner.os == 'Linux' && matrix.go != '1.16'
96+
- if: runner.os == 'Linux'
9797
name: nilness
9898
run: go run golang.org/x/tools/go/analysis/passes/nilness/cmd/nilness@latest ./...
9999

go.mod

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/getkin/kin-openapi
22

3-
go 1.16
3+
go 1.18
44

55
require (
66
github.com/go-openapi/jsonpointer v0.19.5
@@ -9,6 +9,17 @@ require (
99
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
1010
github.com/perimeterx/marshmallow v1.1.4
1111
github.com/stretchr/testify v1.8.1
12-
gopkg.in/yaml.v2 v2.4.0 // indirect
12+
github.com/wk8/go-ordered-map/v2 v2.1.5
1313
gopkg.in/yaml.v3 v3.0.1
1414
)
15+
16+
require (
17+
github.com/bahlo/generic-list-go v0.2.0 // indirect
18+
github.com/buger/jsonparser v1.1.1 // indirect
19+
github.com/davecgh/go-spew v1.1.1 // indirect
20+
github.com/go-openapi/swag v0.19.5 // indirect
21+
github.com/josharian/intern v1.0.0 // indirect
22+
github.com/mailru/easyjson v0.7.7 // indirect
23+
github.com/pmezard/go-difflib v1.0.0 // indirect
24+
gopkg.in/yaml.v2 v2.4.0 // indirect
25+
)

go.sum

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
2+
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
3+
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
4+
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
15
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
26
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
37
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -40,6 +44,8 @@ github.com/ugorji/go v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo=
4044
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
4145
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
4246
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
47+
github.com/wk8/go-ordered-map/v2 v2.1.5 h1:jLbYIFyWQMUwHLO20cImlCRBoNc5lp0nmE2dvwcxc7k=
48+
github.com/wk8/go-ordered-map/v2 v2.1.5/go.mod h1:9Xvgm2mV2kSq2SAm0Y608tBmu8akTzI7c2bz7/G7ZN4=
4349
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
4450
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
4551
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

openapi2/openapi2.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ type T struct {
1818
Produces []string `json:"produces,omitempty" yaml:"produces,omitempty"`
1919
Host string `json:"host,omitempty" yaml:"host,omitempty"`
2020
BasePath string `json:"basePath,omitempty" yaml:"basePath,omitempty"`
21-
Paths map[string]*PathItem `json:"paths,omitempty" yaml:"paths,omitempty"`
21+
Paths *Paths `json:"paths,omitempty" yaml:"paths,omitempty"`
2222
Definitions map[string]*openapi3.SchemaRef `json:"definitions,omitempty" yaml:"definitions,omitempty"`
2323
Parameters map[string]*Parameter `json:"parameters,omitempty" yaml:"parameters,omitempty"`
2424
Responses map[string]*Response `json:"responses,omitempty" yaml:"responses,omitempty"`
@@ -53,8 +53,8 @@ func (doc T) MarshalJSON() ([]byte, error) {
5353
if x := doc.BasePath; x != "" {
5454
m["basePath"] = x
5555
}
56-
if x := doc.Paths; len(x) != 0 {
57-
m["paths"] = x
56+
if x := doc.Paths; x.Len() != 0 {
57+
m["paths"] = x.om
5858
}
5959
if x := doc.Definitions; len(x) != 0 {
6060
m["definitions"] = x
@@ -106,12 +106,12 @@ func (doc *T) UnmarshalJSON(data []byte) error {
106106

107107
func (doc *T) AddOperation(path string, method string, operation *Operation) {
108108
if doc.Paths == nil {
109-
doc.Paths = make(map[string]*PathItem)
109+
doc.Paths = NewPaths()
110110
}
111-
pathItem := doc.Paths[path]
111+
pathItem := doc.Paths.Value(path)
112112
if pathItem == nil {
113113
pathItem = &PathItem{}
114-
doc.Paths[path] = pathItem
114+
doc.Paths.Set(path, pathItem)
115115
}
116116
pathItem.SetOperation(method, operation)
117117
}

openapi2/paths.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package openapi2
2+
3+
import (
4+
"encoding/json"
5+
6+
orderedmap "github.com/wk8/go-ordered-map/v2"
7+
)
8+
9+
type Paths struct {
10+
om *orderedmap.OrderedMap[string, *PathItem]
11+
}
12+
13+
// MarshalJSON returns the JSON encoding of Paths.
14+
func (paths *Paths) MarshalJSON() ([]byte, error) {
15+
if paths == nil || paths.om == nil {
16+
return []byte("{}"), nil
17+
}
18+
return paths.om.MarshalJSON()
19+
}
20+
21+
// UnmarshalJSON sets Paths to a copy of data.
22+
func (paths *Paths) UnmarshalJSON(data []byte) error {
23+
return json.Unmarshal(data, &paths.om)
24+
}
25+
26+
func (paths *Paths) Value(key string) *PathItem {
27+
// if paths == nil || paths.om == nil {
28+
// return nil
29+
// }
30+
return paths.om.Value(key)
31+
}
32+
33+
func (paths *Paths) Set(key string, value *PathItem) {
34+
// if paths != nil || paths.om != nil {
35+
_, _ = paths.om.Set(key, value)
36+
// }
37+
}
38+
39+
func (paths *Paths) Len() int {
40+
if paths == nil || paths.om == nil {
41+
return 0
42+
}
43+
return paths.om.Len()
44+
}
45+
46+
func (paths *Paths) Iter() *pathsKV {
47+
if paths == nil || paths.om == nil {
48+
return nil
49+
}
50+
return (*pathsKV)(paths.om.Oldest())
51+
}
52+
53+
type pathsKV orderedmap.Pair[string, *PathItem] //FIXME: pub?
54+
55+
func (pair *pathsKV) Next() *pathsKV {
56+
ompair := (*orderedmap.Pair[string, *PathItem])(pair)
57+
return (*pathsKV)(ompair.Next())
58+
}
59+
60+
// NewPathsWithCapacity builds a paths object of the given capacity.
61+
func NewPathsWithCapacity(cap int) *Paths {
62+
return &Paths{om: orderedmap.New[string, *PathItem](cap)}
63+
}
64+
65+
// NewPaths builds a paths object with path items in insertion order.
66+
func NewPaths(opts ...NewPathsOption) *Paths {
67+
paths := NewPathsWithCapacity(len(opts))
68+
for _, opt := range opts {
69+
opt(paths)
70+
}
71+
return paths
72+
}
73+
74+
// NewPathsOption describes options to NewPaths func
75+
type NewPathsOption func(*Paths)
76+
77+
// WithPath adds paths as an option to NewPaths
78+
func WithPath(path string, pathItem *PathItem) NewPathsOption {
79+
return func(paths *Paths) { paths.Set(path, pathItem) }
80+
}

openapi2conv/issue558_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ paths:
2727
`
2828
doc3, err := v2v3YAML([]byte(spec))
2929
require.NoError(t, err)
30-
require.NotEmpty(t, doc3.Paths["/test"].Get.Deprecated)
30+
require.NotEmpty(t, doc3.Paths.Value("/test").Get.Deprecated)
3131
_, err = yaml.Marshal(doc3)
3232
require.NoError(t, err)
3333

3434
doc2, err := FromV3(doc3)
3535
require.NoError(t, err)
36-
require.NotEmpty(t, doc2.Paths["/test"].Get.Deprecated)
36+
require.NotEmpty(t, doc2.Paths.Value("/test").Get.Deprecated)
3737
}

openapi2conv/issue573_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@ func TestIssue573(t *testing.T) {
3636

3737
// Make sure the response content appears for each mime-type originally
3838
// appeared in "produces".
39-
pingGetContent := v3.Paths["/ping"].Get.Responses["200"].Value.Content
39+
pingGetContent := v3.Paths.Value("/ping").Get.Responses["200"].Value.Content
4040
require.Len(t, pingGetContent, 2)
4141
require.Contains(t, pingGetContent, "application/toml")
4242
require.Contains(t, pingGetContent, "application/xml")
4343

4444
// Is "produces" is not explicitly specified, default to "application/json".
45-
pingPostContent := v3.Paths["/ping"].Post.Responses["200"].Value.Content
45+
pingPostContent := v3.Paths.Value("/ping").Post.Responses["200"].Value.Content
4646
require.Len(t, pingPostContent, 1)
4747
require.Contains(t, pingPostContent, "application/json")
4848
}

openapi2conv/openapi2_conv.go

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
77
"sort"
88
"strings"
99

10+
orderedmap "github.com/wk8/go-ordered-map/v2"
11+
1012
"github.com/getkin/kin-openapi/openapi2"
1113
"github.com/getkin/kin-openapi/openapi3"
1214
)
@@ -66,16 +68,16 @@ func ToV3(doc2 *openapi2.T) (*openapi3.T, error) {
6668
}
6769
}
6870

69-
if paths := doc2.Paths; len(paths) != 0 {
70-
doc3Paths := make(map[string]*openapi3.PathItem, len(paths))
71-
for path, pathItem := range paths {
71+
if paths := doc2.Paths; paths.Len() != 0 {
72+
doc3.Paths = openapi3.NewPathsWithCapacity(paths.Len())
73+
for pair := paths.Iter(); pair != nil; pair = pair.Next() {
74+
path, pathItem := pair.Key, pair.Value
7275
r, err := ToV3PathItem(doc2, doc3.Components, pathItem, doc2.Consumes)
7376
if err != nil {
7477
return nil, err
7578
}
76-
doc3Paths[path] = r
79+
doc3.Paths.Set(path, r)
7780
}
78-
doc3.Paths = doc3Paths
7981
}
8082

8183
if responses := doc2.Responses; len(responses) != 0 {
@@ -540,9 +542,9 @@ func ToV3SecurityScheme(securityScheme *openapi2.SecurityScheme) (*openapi3.Secu
540542
result.Type = "oauth2"
541543
flows := &openapi3.OAuthFlows{}
542544
result.Flows = flows
543-
scopesMap := make(map[string]string)
545+
scopesMap := orderedmap.New[string, string](len(securityScheme.Scopes))
544546
for scope, desc := range securityScheme.Scopes {
545-
scopesMap[scope] = desc
547+
scopesMap.Set(scope, desc)
546548
}
547549
flow := &openapi3.OAuthFlow{
548550
AuthorizationURL: securityScheme.AuthorizationURL,
@@ -611,7 +613,8 @@ func FromV3(doc3 *openapi3.T) (*openapi2.T, error) {
611613
if isHTTP {
612614
doc2.Schemes = append(doc2.Schemes, "http")
613615
}
614-
for path, pathItem := range doc3.Paths {
616+
for pair := doc3.Paths.Iter(); pair != nil; pair = pair.Next() {
617+
path, pathItem := pair.Key, pair.Value
615618
if pathItem == nil {
616619
continue
617620
}
@@ -636,7 +639,7 @@ func FromV3(doc3 *openapi3.T) (*openapi2.T, error) {
636639
params = append(params, p)
637640
}
638641
sort.Sort(params)
639-
doc2.Paths[path].Parameters = params
642+
doc2.Paths.Value(path).Parameters = params
640643
}
641644

642645
for name, param := range doc3.Components.Parameters {
@@ -1155,9 +1158,9 @@ func FromV3SecurityScheme(doc3 *openapi3.T, ref *openapi3.SecuritySchemeRef) (*o
11551158
return nil, nil
11561159
}
11571160

1158-
result.Scopes = make(map[string]string, len(flow.Scopes))
1159-
for scope, desc := range flow.Scopes {
1160-
result.Scopes[scope] = desc
1161+
result.Scopes = make(map[string]string, flow.Scopes.Len())
1162+
for pair := flow.Scopes.Oldest(); pair != nil; pair = pair.Next() {
1163+
result.Scopes[pair.Key] = pair.Value
11611164
}
11621165
}
11631166
default:
@@ -1183,12 +1186,12 @@ func stripNonExtensions(extensions map[string]interface{}) map[string]interface{
11831186

11841187
func addPathExtensions(doc2 *openapi2.T, path string, extensions map[string]interface{}) {
11851188
if doc2.Paths == nil {
1186-
doc2.Paths = make(map[string]*openapi2.PathItem)
1189+
doc2.Paths = openapi2.NewPaths()
11871190
}
1188-
pathItem := doc2.Paths[path]
1191+
pathItem := doc2.Paths.Value(path)
11891192
if pathItem == nil {
11901193
pathItem = &openapi2.PathItem{}
1191-
doc2.Paths[path] = pathItem
1194+
doc2.Paths.Set(path, pathItem)
11921195
}
11931196
pathItem.Extensions = extensions
11941197
}

0 commit comments

Comments
 (0)