-
Notifications
You must be signed in to change notification settings - Fork 8
/
mapslice.go
76 lines (66 loc) · 1.53 KB
/
mapslice.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package mapslice
import (
"bytes"
"encoding/json"
"fmt"
"sort"
)
// MapItem representation of one map item.
type MapItem struct {
Key, Value interface{}
index uint64
}
// MapSlice of map items.
type MapSlice []MapItem
func (ms MapSlice) Len() int { return len(ms) }
func (ms MapSlice) Less(i, j int) bool { return ms[i].index < ms[j].index }
func (ms MapSlice) Swap(i, j int) { ms[i], ms[j] = ms[j], ms[i] }
var indexCounter uint64
func nextIndex() uint64 {
indexCounter++
return indexCounter
}
// MapItem as a string.
func (mi MapItem) String() string {
return fmt.Sprintf("{%v %v}", mi.Key, mi.Value)
}
// MarshalJSON for map slice.
func (ms MapSlice) MarshalJSON() ([]byte, error) {
buf := &bytes.Buffer{}
buf.Write([]byte{'{'})
for i, mi := range ms {
b, err := json.Marshal(&mi.Value)
if err != nil {
return nil, err
}
buf.WriteString(fmt.Sprintf("%q:", fmt.Sprint(mi.Key)))
buf.Write(b)
if i < len(ms)-1 {
buf.Write([]byte{','})
}
}
buf.Write([]byte{'}'})
return buf.Bytes(), nil
}
// UnmarshalJSON for map slice.
func (ms *MapSlice) UnmarshalJSON(b []byte) error {
m := map[string]MapItem{}
if err := json.Unmarshal(b, &m); err != nil {
return err
}
for k, v := range m {
*ms = append(*ms, MapItem{Key: k, Value: v.Value, index: v.index})
}
sort.Sort(*ms)
return nil
}
// UnmarshalJSON for map item.
func (mi *MapItem) UnmarshalJSON(b []byte) error {
var v interface{}
if err := json.Unmarshal(b, &v); err != nil {
return err
}
mi.Value = v
mi.index = nextIndex()
return nil
}