-
Notifications
You must be signed in to change notification settings - Fork 503
/
proto.go
49 lines (43 loc) · 1.05 KB
/
proto.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
package internal
import (
"encoding/json"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/proto"
"gopkg.in/yaml.v2"
)
// ProtoFromYaml converts a YAML string into the specific protobuf message.
func ProtoFromYaml(s []byte, m proto.Message) error {
var obj interface{}
if err := yaml.Unmarshal(s, &obj); err != nil {
return err
}
obj = convert(obj)
// Encode YAML to JSON.
rawJSON, err := json.Marshal(obj)
if err != nil {
return err
}
// Use protojson to convert the JSON into the desired proto.
err = protojson.Unmarshal(rawJSON, m)
if err != nil {
return err
}
return nil
}
// This is necessary because yaml.Unmarshal gives us map[interface{}]interface{} and we need
// to cast the types in order to make json.Marshal accept it.
func convert(i interface{}) interface{} {
switch x := i.(type) {
case map[interface{}]interface{}:
m2 := map[string]interface{}{}
for k, v := range x {
m2[k.(string)] = convert(v)
}
return m2
case []interface{}:
for i, v := range x {
x[i] = convert(v)
}
}
return i
}