-
Notifications
You must be signed in to change notification settings - Fork 670
/
marshal_utils.go
123 lines (99 loc) · 3.4 KB
/
marshal_utils.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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package utils
import (
"bytes"
"encoding/json"
"fmt"
"strings"
"github.com/golang/protobuf/jsonpb"
"github.com/golang/protobuf/proto"
structpb "github.com/golang/protobuf/ptypes/struct"
"github.com/pkg/errors"
)
var jsonPbMarshaler = jsonpb.Marshaler{}
var jsonPbUnmarshaler = jsonpb.Unmarshaler{
AllowUnknownFields: true,
}
// UnmarshalStructToPb unmarshals a proto struct into a proto message using jsonPb marshaler.
func UnmarshalStructToPb(structObj *structpb.Struct, msg proto.Message) error {
if structObj == nil {
return fmt.Errorf("nil Struct object passed")
}
if msg == nil {
return fmt.Errorf("nil proto.Message object passed")
}
jsonObj, err := jsonPbMarshaler.MarshalToString(structObj)
if err != nil {
return errors.WithMessage(err, "Failed to marshal strcutObj input")
}
if err = UnmarshalStringToPb(jsonObj, msg); err != nil {
return errors.WithMessage(err, "Failed to unmarshal json obj into proto")
}
return nil
}
// MarshalPbToStruct marshals a proto message into proto Struct using jsonPb marshaler.
func MarshalPbToStruct(in proto.Message) (out *structpb.Struct, err error) {
if in == nil {
return nil, fmt.Errorf("nil proto message passed")
}
var buf bytes.Buffer
if err := jsonPbMarshaler.Marshal(&buf, in); err != nil {
return nil, errors.WithMessage(err, "Failed to marshal input proto message")
}
out = &structpb.Struct{}
if err = UnmarshalBytesToPb(buf.Bytes(), out); err != nil {
return nil, errors.WithMessage(err, "Failed to unmarshal json object into struct")
}
return out, nil
}
// MarshalPbToString marshals a proto message using jsonPb marshaler to string.
func MarshalPbToString(msg proto.Message) (string, error) {
return jsonPbMarshaler.MarshalToString(msg)
}
// UnmarshalStringToPb unmarshals a string to a proto message
func UnmarshalStringToPb(s string, msg proto.Message) error {
return jsonPbUnmarshaler.Unmarshal(strings.NewReader(s), msg)
}
// MarshalPbToBytes marshals a proto message to a byte slice
func MarshalPbToBytes(msg proto.Message) ([]byte, error) {
var buf bytes.Buffer
err := jsonPbMarshaler.Marshal(&buf, msg)
if err != nil {
return nil, err
}
return buf.Bytes(), err
}
// UnmarshalBytesToPb unmarshals a byte slice to a proto message
func UnmarshalBytesToPb(b []byte, msg proto.Message) error {
return jsonPbUnmarshaler.Unmarshal(bytes.NewReader(b), msg)
}
// MarshalObjToStruct marshals obj into a struct. Will use jsonPb if input is a proto message, otherwise, it'll use json
// marshaler.
func MarshalObjToStruct(input interface{}) (*structpb.Struct, error) {
if p, casted := input.(proto.Message); casted {
return MarshalPbToStruct(p)
}
b, err := json.Marshal(input)
if err != nil {
return nil, errors.WithMessage(err, "Failed to marshal input proto message")
}
// Turn JSON into a protobuf struct
structObj := &structpb.Struct{}
if err := UnmarshalBytesToPb(b, structObj); err != nil {
return nil, errors.WithMessage(err, "Failed to unmarshal json object into struct")
}
return structObj, nil
}
// UnmarshalStructToObj unmarshals a struct to the passed obj. Don't use this if the unmarshalled obj is a proto message.
func UnmarshalStructToObj(structObj *structpb.Struct, obj interface{}) error {
if structObj == nil {
return fmt.Errorf("nil Struct Object passed")
}
jsonObj, err := json.Marshal(structObj)
if err != nil {
return err
}
if err = json.Unmarshal(jsonObj, obj); err != nil {
return err
}
return nil
}