@@ -27,7 +27,7 @@ names+=('paths')
2727[[ " ${# types[@]} " = " ${# value_types[@]} " ]]
2828[[ " ${# types[@]} " = " ${# deref_vs[@]} " ]]
2929[[ " ${# types[@]} " = " ${# names[@]} " ]]
30- [[ " ${# types[@]} " = " $( git grep -InF ' m map[string]*' -- openapi3/loader.go | wc -l) " ]]
30+ [[ " ${# types[@]} " = " $( git grep -InF ' om map[string]*' -- openapi3/loader.go | wc -l) " ]] # FIXME: !map
3131
3232
3333maplike_header () {
@@ -36,10 +36,10 @@ package openapi3
3636
3737import (
3838 "encoding/json"
39- "sort"
4039 "strings"
4140
4241 "github.com/go-openapi/jsonpointer"
42+ orderedmap "github.com/wk8/go-ordered-map/v2"
4343)
4444
4545EOF
@@ -73,9 +73,9 @@ maplike_NewWithCapa() {
7373// New${type# ' *' } WithCapacity builds a ${name} object of the given capacity.
7474func New${type# ' *' } WithCapacity(cap int) ${type} {
7575 if cap == 0 {
76- return &${type# ' *' } {m: make(map [string] ${value_type} )}
76+ return &${type# ' *' } {om: orderedmap.New [string, ${value_type} ]( )}
7777 }
78- return &${type# ' *' } {m: make(map [string] ${value_type} , cap)}
78+ return &${type# ' *' } {om: orderedmap.New [string, ${value_type} ]( cap)}
7979}
8080
8181EOF
@@ -89,35 +89,35 @@ func (${name} ${type}) Value(key string) ${value_type} {
8989 if ${name} .Len() == 0 {
9090 return nil
9191 }
92- return ${name} .m[ key]
92+ return ${name} .om.Value( key)
9393}
9494
9595// Set adds or replaces key 'key' of '${name} ' with 'value'.
9696// Note: '${name} ' MUST be non-nil
9797func (${name} ${type} ) Set(key string, value ${value_type} ) {
98- if ${name} .m == nil {
99- ${name} .m = make(map[string] ${value_type} )
98+ if ${name} .om == nil {
99+ ${name} .om = New ${type # ' * ' } WithCapacity(0).om
100100 }
101- ${name} .m[ key] = value
101+ _, _ = ${name} .om.Set( key, value)
102102}
103103
104104// Len returns the amount of keys in ${name} excluding ${name} .Extensions.
105105func (${name} ${type} ) Len() int {
106- if ${name} == nil || ${name} .m == nil {
106+ if ${name} == nil || ${name} .om == nil {
107107 return 0
108108 }
109- return len( ${name} .m )
109+ return ${name} .om.Len( )
110110}
111111
112112// Map returns ${name} as a 'map'.
113113// Note: iteration on Go maps is not ordered.
114114func (${name} ${type} ) Map() (m map[string]${value_type} ) {
115- if ${name} == nil || len( ${name} .m) == 0 {
115+ if ${name} == nil || ${name} .om == nil {
116116 return make(map[string]${value_type} )
117117 }
118- m = make(map[string]${value_type} , len( ${name} .m ))
119- for k, v := range ${name} .m {
120- m[k ] = v
118+ m = make(map[string]${value_type} , ${name} .Len( ))
119+ for pair := ${name} .Iter(); pair != nil; pair = pair.Next() {
120+ m[pair.Key ] = pair.Value
121121 }
122122 return
123123}
126126}
127127
128128
129+ maplike_IterNext () {
130+ cat << EOF >>"$maplike "
131+ type ${name} KV orderedmap.Pair[string, ${value_type} ] //FIXME: pub?
132+ // Iter returns a pointer to the first pair, in insertion order.
133+ func (${name} ${type} ) Iter() *${name} KV {
134+ if ${name} .Len() == 0 {
135+ return nil
136+ }
137+ return (*${name} KV)(${name} .om.Oldest())
138+ }
139+
140+ // Next returns a pointer to the next pair, in insertion order.
141+ func (pair *${name} KV) Next() *${name} KV {
142+ ompair := (*orderedmap.Pair[string, ${value_type} ])(pair)
143+ return (*${name} KV)(ompair.Next())
144+ }
145+
146+ EOF
147+ }
148+
149+
129150maplike_Pointable () {
130151 cat << EOF >>"$maplike "
131152var _ jsonpointer.JSONPointable = (${type} )(nil)
@@ -151,36 +172,28 @@ maplike_UnMarsh() {
151172 cat << EOF >>"$maplike "
152173// MarshalJSON returns the JSON encoding of ${type# ' *' } .
153174func (${name} ${type} ) MarshalJSON() ([]byte, error) {
154- m := make(map [string] interface{}, ${name} .Len()+ len(${name} .Extensions))
155- for k, v := range ${name} .Extensions {
156- m[k] = v
175+ om := orderedmap.New [string, interface{}]( ${name} .Len() + len(${name} .Extensions))
176+ for pair := ${name} .Iter(); pair != nil; pair = pair.Next() {
177+ om.Set(pair.Key, pair.Value)
157178 }
158- for k, v := range ${name} .Map() {
159- m[k] = v
179+ for k, v := range ${name} .Extensions {
180+ om.Set(k, v)
160181 }
161- return json.Marshal(m )
182+ return om.MarshalJSON( )
162183}
163184
164185// UnmarshalJSON sets ${type# ' *' } to a copy of data.
165186func (${name} ${type} ) UnmarshalJSON(data []byte) (err error) {
166- var m map [string] interface{}
167- if err = json.Unmarshal(data, &m ); err != nil {
187+ om := orderedmap.New [string, interface{}]()
188+ if err = json.Unmarshal(data, &om ); err != nil {
168189 return
169190 }
170191
171- ks := make([]string, 0, len(m))
172- for k := range m {
173- ks = append(ks, k)
174- }
175- sort.Strings(ks)
176-
177- x := ${type# ' *' } {
178- Extensions: make(map[string]interface{}),
179- m: make(map[string]${value_type} , len(m)),
180- }
192+ x := New${type# ' *' } WithCapacity(om.Len())
193+ x.Extensions = make(map[string]interface{})
181194
182- for _, k := range ks {
183- v := m[k]
195+ for pair := om.Oldest(); pair != nil; pair = pair.Next() {
196+ k, v := pair.Key, pair.Value
184197 if strings.HasPrefix(k, "x-") {
185198 x.Extensions[k] = v
186199 continue
@@ -194,9 +207,9 @@ func (${name} ${type}) UnmarshalJSON(data []byte) (err error) {
194207 if err = vv.UnmarshalJSON(data); err != nil {
195208 return
196209 }
197- x.m[k] = &vv
210+ x.Set(k, &vv)
198211 }
199- *${name} = x
212+ *${name} = * x
200213 return
201214}
202215EOF
@@ -221,8 +234,10 @@ test_body() {
221234 require.Equal(t, (${value_type} )(nil), x.Value("key"))
222235 x.Set("key", &${value_type# ' *' } {})
223236 require.Equal(t, 1, x.Len())
224- require.Equal(t, map[string]${value_type} {"key": {}}, x.Map())
225- require.Equal(t, &${value_type# ' *' } {}, x.Value("key"))
237+ m := x.Map()
238+ require.Equal(t, map[string]${value_type} {"key": {}}, m)
239+ m["key"].Ref = "bla"
240+ require.Equal(t, &${value_type# ' *' } {Ref: "bla"}, x.Value("key"))
226241 })
227242 })
228243
@@ -242,6 +257,7 @@ for i in "${!types[@]}"; do
242257
243258 type=" $type " name=" $name " value_type=" $value_type " maplike_NewWithCapa
244259 type=" $type " name=" $name " value_type=" $value_type " maplike_ValueSetLen
260+ type=" $type " name=" $name " value_type=" $value_type " maplike_IterNext
245261 type=" $type " name=" $name " deref_v=" $deref_v " maplike_Pointable
246262 type=" $type " name=" $name " value_type=" $value_type " maplike_UnMarsh
247263 [[ $(( i+ 1 )) != " ${# types[@]} " ]] && echo >> " $maplike "
0 commit comments