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"
"github.com/bufbuild/protoyaml-go"
)
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: no
The 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"
"github.com/bufbuild/protoyaml-go"
"github.com/bufbuild/protovalidate-go"
)
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