json.go raw
1 package api
2
3 import (
4 "reflect"
5
6 jsoniter "github.com/json-iterator/go"
7 "github.com/mimuret/golang-iij-dpf/pkg/meta"
8 )
9
10 var JSON = NewJSONAPIAdapter()
11
12 func UnmarshalRead(bs []byte, o interface{}) error {
13 return JSON.UnmarshalRead(bs, o)
14 }
15
16 func MarshalCreate(body interface{}) ([]byte, error) {
17 return JSON.MarshalCreate(body)
18 }
19
20 func MarshalUpdate(body interface{}) ([]byte, error) {
21 return JSON.MarshalUpdate(body)
22 }
23
24 func MarshalApply(body interface{}) ([]byte, error) {
25 return JSON.MarshalApply(body)
26 }
27
28 func MarshalOutput(spec Spec) ([]byte, error) {
29 return JSON.MarshalOutput(spec)
30 }
31
32 func UnMarshalInput(bs []byte, obj Object) error {
33 return JSON.UnMarshalInput(bs, obj)
34 }
35
36 type JSONAPIInterface interface {
37 UnmarshalRead(bs []byte, o interface{}) error
38 MarshalCreate(body interface{}) ([]byte, error)
39 MarshalUpdate(body interface{}) ([]byte, error)
40 MarshalApply(body interface{}) ([]byte, error)
41 }
42
43 type JSONFileInterface interface {
44 MarshalOutput(spec Spec) ([]byte, error)
45 UnMarshalInput(bs []byte, obj Object) error
46 }
47
48 type JSONAPIAdapter struct {
49 Read jsoniter.API
50 Update jsoniter.API
51 Create jsoniter.API
52 Apply jsoniter.API
53 JSON jsoniter.API
54 }
55
56 func NewJSONAPIAdapter() *JSONAPIAdapter {
57 return &JSONAPIAdapter{
58 Read: jsoniter.Config{
59 EscapeHTML: true,
60 SortMapKeys: false,
61 ValidateJsonRawMessage: true,
62 OnlyTaggedField: true,
63 TagKey: "read",
64 }.Froze(),
65 Create: jsoniter.Config{
66 EscapeHTML: true,
67 SortMapKeys: true,
68 ValidateJsonRawMessage: true,
69 OnlyTaggedField: true,
70 TagKey: "create",
71 }.Froze(),
72 Update: jsoniter.Config{
73 EscapeHTML: true,
74 SortMapKeys: true,
75 ValidateJsonRawMessage: true,
76 OnlyTaggedField: true,
77 TagKey: "update",
78 }.Froze(),
79 Apply: jsoniter.Config{
80 EscapeHTML: true,
81 SortMapKeys: true,
82 ValidateJsonRawMessage: true,
83 OnlyTaggedField: true,
84 TagKey: "apply",
85 }.Froze(),
86 JSON: jsoniter.Config{
87 EscapeHTML: true,
88 SortMapKeys: true,
89 ValidateJsonRawMessage: true,
90 OnlyTaggedField: false,
91 TagKey: "json",
92 }.Froze(),
93 }
94 }
95
96 // Unmarshal api response.
97 func (j *JSONAPIAdapter) UnmarshalRead(bs []byte, o interface{}) error {
98 return j.Read.Unmarshal(bs, o)
99 }
100
101 // Marshal for create request.
102 func (j *JSONAPIAdapter) MarshalCreate(body interface{}) ([]byte, error) {
103 return j.Create.Marshal(body)
104 }
105
106 // Marshal for update request.
107 func (j *JSONAPIAdapter) MarshalUpdate(body interface{}) ([]byte, error) {
108 return j.Update.Marshal(body)
109 }
110
111 // Marshal for apply request.
112 func (j *JSONAPIAdapter) MarshalApply(body interface{}) ([]byte, error) {
113 return j.Apply.Marshal(body)
114 }
115
116 // file format frame.
117 type OutputFrame struct {
118 meta.KindVersion `json:",inline"`
119 Resource Object `json:"resource"`
120 }
121
122 // Marshal for file format.
123 func (j *JSONAPIAdapter) MarshalOutput(spec Spec) ([]byte, error) {
124 t := reflect.TypeOf(spec)
125 t = t.Elem()
126 out := &OutputFrame{
127 KindVersion: meta.KindVersion{
128 Kind: t.Name(),
129 APIVersion: spec.GetGroup(),
130 },
131 Resource: spec,
132 }
133 return j.JSON.Marshal(out)
134 }
135
136 // UnMarshal for file format.
137 func (j *JSONAPIAdapter) UnMarshalInput(bs []byte, obj Object) error {
138 out := &OutputFrame{
139 Resource: obj,
140 }
141 return j.JSON.Unmarshal(bs, out)
142 }
143