@@ -2,13 +2,15 @@ package collections
22
33import (
44 "bytes"
5+ "encoding"
56 "encoding/json"
67 "errors"
78 "fmt"
89 "iter"
910 "maps"
1011 "reflect"
1112 "slices"
13+ "strconv"
1214
1315 json2 "github.com/go-json-experiment/json"
1416 "github.com/go-json-experiment/json/jsontext"
@@ -105,6 +107,10 @@ func (m *OrderedMap[K, V]) Delete(key K) (V, bool) {
105107// A slice of the keys can be obtained by calling `slices.Collect`.
106108func (m * OrderedMap [K , V ]) Keys () iter.Seq [K ] {
107109 return func (yield func (K ) bool ) {
110+ if m == nil {
111+ return
112+ }
113+
108114 // We use a for loop here to ensure we enumerate new items added during iteration.
109115 //nolint:intrange
110116 for i := 0 ; i < len (m .keys ); i ++ {
@@ -119,6 +125,10 @@ func (m *OrderedMap[K, V]) Keys() iter.Seq[K] {
119125// A slice of the values can be obtained by calling `slices.Collect`.
120126func (m * OrderedMap [K , V ]) Values () iter.Seq [V ] {
121127 return func (yield func (V ) bool ) {
128+ if m == nil {
129+ return
130+ }
131+
122132 // We use a for loop here to ensure we enumerate new items added during iteration.
123133 //nolint:intrange
124134 for i := 0 ; i < len (m .keys ); i ++ {
@@ -132,6 +142,10 @@ func (m *OrderedMap[K, V]) Values() iter.Seq[V] {
132142// Entries returns an iterator over the key-value pairs in the map.
133143func (m * OrderedMap [K , V ]) Entries () iter.Seq2 [K , V ] {
134144 return func (yield func (K , V ) bool ) {
145+ if m == nil {
146+ return
147+ }
148+
135149 // We use a for loop here to ensure we enumerate new items added during iteration.
136150 //nolint:intrange
137151 for i := 0 ; i < len (m .keys ); i ++ {
@@ -153,11 +167,19 @@ func (m *OrderedMap[K, V]) Clear() {
153167
154168// Size returns the number of key-value pairs in the map.
155169func (m * OrderedMap [K , V ]) Size () int {
170+ if m == nil {
171+ return 0
172+ }
173+
156174 return len (m .keys )
157175}
158176
159177// Clone returns a shallow copy of the map.
160178func (m * OrderedMap [K , V ]) Clone () * OrderedMap [K , V ] {
179+ if m == nil {
180+ return nil
181+ }
182+
161183 m2 := m .clone ()
162184 return & m2
163185}
@@ -169,6 +191,59 @@ func (m *OrderedMap[K, V]) clone() OrderedMap[K, V] {
169191 }
170192}
171193
194+ func (m OrderedMap [K , V ]) MarshalJSON () ([]byte , error ) {
195+ if len (m .mp ) == 0 {
196+ return []byte ("{}" ), nil
197+ }
198+ var buf bytes.Buffer
199+ buf .WriteByte ('{' )
200+ enc := json .NewEncoder (& buf )
201+ enc .SetEscapeHTML (false )
202+
203+ for i , k := range m .keys {
204+ if i > 0 {
205+ buf .WriteByte (',' )
206+ }
207+
208+ keyString , err := resolveKeyName (reflect .ValueOf (k ))
209+ if err != nil {
210+ return nil , err
211+ }
212+
213+ if err := enc .Encode (keyString ); err != nil {
214+ return nil , err
215+ }
216+
217+ buf .WriteByte (':' )
218+
219+ if err := enc .Encode (m .mp [k ]); err != nil {
220+ return nil , err
221+ }
222+ }
223+ buf .WriteByte ('}' )
224+ return buf .Bytes (), nil
225+ }
226+
227+ func resolveKeyName (k reflect.Value ) (string , error ) {
228+ if k .Kind () == reflect .String {
229+ return k .String (), nil
230+ }
231+ if tm , ok := k .Interface ().(encoding.TextMarshaler ); ok {
232+ if k .Kind () == reflect .Pointer && k .IsNil () {
233+ return "" , nil
234+ }
235+ buf , err := tm .MarshalText ()
236+ return string (buf ), err
237+ }
238+ switch k .Kind () {
239+ case reflect .Int , reflect .Int8 , reflect .Int16 , reflect .Int32 , reflect .Int64 :
240+ return strconv .FormatInt (k .Int (), 10 ), nil
241+ case reflect .Uint , reflect .Uint8 , reflect .Uint16 , reflect .Uint32 , reflect .Uint64 , reflect .Uintptr :
242+ return strconv .FormatUint (k .Uint (), 10 ), nil
243+ }
244+ panic ("unexpected map key type" )
245+ }
246+
172247func (m * OrderedMap [K , V ]) UnmarshalJSON (data []byte ) error {
173248 if string (data ) == "null" {
174249 // By convention, to approximate the behavior of Unmarshal itself,
0 commit comments