-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathcollection.go
93 lines (71 loc) · 2 KB
/
collection.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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package jsonapi
import "encoding/json"
// A Collection defines the interface of a structure that can manage a set of
// ordered resources of the same type.
type Collection interface {
// GetType returns the type of the resources.
GetType() Type
// Len returns the number of resources in the collection.
Len() int
// At returns the resource at index i.
At(int) Resource
// Add adds a resource in the collection.
Add(Resource)
}
// MarshalCollection marshals a Collection into a JSON-encoded payload.
func MarshalCollection(c Collection, prepath string, fields map[string][]string, relData map[string][]string) []byte {
var raws []*json.RawMessage
if c.Len() == 0 {
return []byte("[]")
}
for i := 0; i < c.Len(); i++ {
r := c.At(i)
raw := json.RawMessage(
MarshalResource(r, prepath, fields[r.GetType().Name], relData),
)
raws = append(raws, &raw)
}
// NOTE An error should not happen.
pl, _ := json.Marshal(raws)
return pl
}
// UnmarshalCollection unmarshals a JSON-encoded payload into a Collection.
func UnmarshalCollection(data []byte, schema *Schema) (Collection, error) {
var cske []json.RawMessage
err := json.Unmarshal(data, &cske)
if err != nil {
return nil, err
}
col := &Resources{}
for i := range cske {
res, err := UnmarshalResource(cske[i], schema)
if err != nil {
return nil, err
}
col.Add(res)
}
return col, nil
}
// Resources is a slice of objects that implement the Resource interface. They
// do not necessarily have the same type.
type Resources []Resource
// GetType returns a zero Type object because the collection does not represent
// a particular type.
func (r *Resources) GetType() Type {
return Type{}
}
// Len returns the number of elements in r.
func (r *Resources) Len() int {
return len(*r)
}
// At returns the number of elements in r.
func (r *Resources) At(i int) Resource {
if i >= 0 && i < r.Len() {
return (*r)[i]
}
return nil
}
// Add adds a Resource object to r.
func (r *Resources) Add(res Resource) {
*r = append(*r, res)
}