/
util.go
100 lines (90 loc) · 2.39 KB
/
util.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
94
95
96
97
98
99
100
package cri
import (
"bytes"
"encoding/json"
"fmt"
"reflect"
"sort"
"strings"
"github.com/gogo/protobuf/jsonpb"
"github.com/golang/protobuf/proto"
)
const (
formatJSON = "json"
formatGoTemplate = "go-template"
)
func protobufObjectToJSON(obj proto.Message) (string, error) {
jsonpbMarshaler := jsonpb.Marshaler{EmitDefaults: true, Indent: " "}
marshaledJSON, err := jsonpbMarshaler.MarshalToString(obj)
if err != nil {
return "", err
}
return marshaledJSON, nil
}
func outputStatusInfo(status string, info map[string]string, format, tmplStr string) (string, error) {
// Sort all keys
keys := []string{}
for k := range info {
keys = append(keys, k)
}
sort.Strings(keys)
jsonInfo := "{" + "\"status\":" + status + ","
for _, k := range keys {
var res interface{}
// We attempt to convert key into JSON if possible else use it directly
if err := json.Unmarshal([]byte(info[k]), &res); err != nil {
jsonInfo += "\"" + k + "\"" + ":" + "\"" + info[k] + "\","
} else {
jsonInfo += "\"" + k + "\"" + ":" + info[k] + ","
}
}
jsonInfo = jsonInfo[:len(jsonInfo)-1]
jsonInfo += "}"
switch format {
case formatJSON:
var output bytes.Buffer
if err := json.Indent(&output, []byte(jsonInfo), "", " "); err != nil {
return "", err
}
return output.String(), nil
case formatGoTemplate:
return tmplExecuteRawJSON(tmplStr, jsonInfo)
default:
return "", fmt.Errorf("unsupported %q format\n", format)
}
}
// marshalMapInOrder marshalls a map into json in the order of the original
// data structure.
func marshalMapInOrder(m map[string]interface{}, t interface{}) (string, error) {
s := "{"
v := reflect.ValueOf(t)
for i := 0; i < v.Type().NumField(); i++ {
field := jsonFieldFromTag(v.Type().Field(i).Tag)
if field == "" || field == "-" {
continue
}
value, err := json.Marshal(m[field])
if err != nil {
return "", err
}
s += fmt.Sprintf("%q:%s,", field, value)
}
s = s[:len(s)-1]
s += "}"
var buf bytes.Buffer
if err := json.Indent(&buf, []byte(s), "", " "); err != nil {
return "", err
}
return buf.String(), nil
}
// jsonFieldFromTag gets json field name from field tag.
func jsonFieldFromTag(tag reflect.StructTag) string {
field := strings.Split(tag.Get("json"), ",")[0]
for _, f := range strings.Split(tag.Get("protobuf"), ",") {
if !strings.HasPrefix(f, "json=") {
continue
}
field = strings.TrimPrefix(f, "json=")
}
return field
}