Marshal and unmarshal Protocol Buffers as YAML. Provides fine-grained error details with file, line, column and snippet information.
Fully compatible with protojson.
package main
import (
"log"
"buf.build/go/protoyaml"
)
func main() {
// Marshal a proto message to YAML.
yamlBytes, err := protoyaml.Marshal(
&pb.MyMessage{
MyField: "hello world",
},
)
if err != nil {
log.Fatal(err)
}
// Unmarshal a proto message from YAML.
options := protoyaml.UnmarshalOptions{
Path: "testdata/basic.proto3test.yaml",
}
var myMessage pb.MyMessage
if err := options.Unmarshal(yamlBytes, &myMessage); err != nil {
log.Fatal(err)
}
}ProtoYAML returns either nil or an error with a detailed message. For every error found in the file, the error
message includes the file name (if Path is set on UnmarshalOptions), line number, column number, and snippet
of the YAML that caused the error. For example, when unmarshalling the following YAML file:
values:
- single_bool: true
- single_bool: false
- single_bool: 1
- single_bool: 0
- single_bool: "true"
- single_bool: "false"
- single_bool: True
- single_bool: False
- single_bool: TRUE
- single_bool: FALSE
- single_bool: yes
- single_bool: noThe following errors are returned:
testdata/basic.proto3test.yaml:5:18: expected bool, got "1"
5 | - single_bool: 1
| .................^
testdata/basic.proto3test.yaml:6:18: expected bool, got "0"
6 | - single_bool: 0
| .................^
testdata/basic.proto3test.yaml:7:18: expected tag !!bool, got !!str
7 | - single_bool: "true"
| .................^
testdata/basic.proto3test.yaml:8:18: expected tag !!bool, got !!str
8 | - single_bool: "false"
| .................^
testdata/basic.proto3test.yaml:9:18: expected bool, got "True"
9 | - single_bool: True
| .................^
testdata/basic.proto3test.yaml:10:18: expected bool, got "False"
10 | - single_bool: False
| .................^
testdata/basic.proto3test.yaml:11:18: expected bool, got "TRUE"
11 | - single_bool: TRUE
| .................^
testdata/basic.proto3test.yaml:12:18: expected bool, got "FALSE"
12 | - single_bool: FALSE
| .................^
testdata/basic.proto3test.yaml:13:18: expected bool, got "yes"
13 | - single_bool: yes
| .................^
testdata/basic.proto3test.yaml:14:18: expected bool, got "no"
14 | - single_bool: no
| .................^
Only true and false are valid values for the single_bool field.
For more examples, see the internal/testdata directory.
ProtoYAML can integrate with external validation libraries such as
Protovalidate to provide additional rich error
information. Simply provide a Validator to the UnmarshalOptions:
package main
import (
"log"
"buf.build/go/protoyaml"
"buf.build/go/protovalidate"
)
func main() {
validator, err := protovalidate.NewValidator()
if err != nil {
log.Fatal(err)
}
var myMessage pb.MyMessage
options := protoyaml.UnmarshalOptions{
Path: "testdata/basic.proto3test.yaml",
Validator: validator,
}
if err := options.Unmarshal(yamlBytes, &myMessage); err != nil {
log.Fatal(err)
}
}The errors produced by the Validator will show up along side the ProtoYAML errors. For example:
testdata/validate.validate.yaml:4:18 cases[2].float_gt_lt: value must be greater than 0 and less than 10 (float.gt_lt)
4 | - float_gt_lt: 10.5
| .................^
ProtoYAML is not yet stable. However, the final shape is unlikely to change drastically—future edits will be somewhat minor.
Offered under the Apache 2 license