-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathobject.go
More file actions
92 lines (74 loc) · 1.8 KB
/
object.go
File metadata and controls
92 lines (74 loc) · 1.8 KB
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package orderedobject
import (
"bytes"
jsoniter "github.com/json-iterator/go"
)
// Pair represents a key value pair.
type Pair[V any] struct {
// Key is the pair's key.
Key string
// Value is the pair's value.
Value V
}
// Object represents a JSON object that respects insertion order.
type Object[V any] []*Pair[V]
// NewObject creates a new Object with the specified capacity.
func NewObject[V any](capacity int) *Object[V] {
obj := make(Object[V], 0, capacity)
return &obj
}
// Set sets key in object with the given value.
//
// The key is replaced if it already exists.
func (object *Object[V]) Set(key string, value V) {
for i, pair := range *object {
if pair.Key == key {
(*object)[i].Value = value
return
}
}
*object = append(*object, &Pair[V]{key, value})
}
// Has reports if the given key is set.
func (object *Object[V]) Has(key string) bool {
for _, pair := range *object {
if pair.Key == key {
return true
}
}
return false
}
// Get gets the value of key.
//
// The returned value is V's zero value if key isn't set.
func (object *Object[V]) Get(key string) V {
for _, pair := range *object {
if pair.Key == key {
return pair.Value
}
}
// "hack" to get V's zero value
var empty V
return empty
}
// MarshalJSON encodes the object into JSON format, respecting insertion order in the process.
func (object *Object[V]) MarshalJSON() ([]byte, error) {
var builder bytes.Buffer
encoder := jsoniter.NewEncoder(&builder)
encoder.SetEscapeHTML(false)
builder.WriteString("{")
for i, pair := range *object {
if i > 0 {
builder.WriteString(",")
}
builder.WriteString(`"`)
builder.WriteString(pair.Key)
builder.WriteString(`":`)
err := encoder.Encode(pair.Value)
if err != nil {
return nil, err
}
}
builder.WriteString("}")
return builder.Bytes(), nil
}