I have a struct with a byte array as a field. Here's the code:
package main
import (
"fmt"
"gopkg.in/yaml.v3"
)
type A struct {
PublicKey []byte `json:"PublicKey" yaml:"PublicKey"`
}
// Implements the Marshaler interface of the yaml pkg.
func (a A) MarshalYAML() (interface{}, error) {
type alias A
node := yaml.Node{}
_ = node.Encode(alias(a))
return node, nil
}
func PublicKey() {
token := []byte{87, 88, 89, 90}
a := A{PublicKey: token}
fmt.Printf("A: % v\nA.PublicKey:%s\n\n", a, a.PublicKey)
out, _ := yaml.Marshal(a)
fmt.Println(string(out))
}
func main() {
PublicKey()
}
Here's the output:
A: {PublicKey:[87 88 89 90]}
A.PublicKey:WXYZ
PublicKey:
- 87
- 88
- 89
- 90
Is it possible to have the unmarshal-er output it as a string instead of a byte array? E.g.:
PublicKey: WXYZ
CodePudding user response:
Instead of customizing codec for A
I'd rather make custom type for the public key and use Base64 to encode/decode its value
type PubKey []byte
func (pk PubKey) MarshalYAML() (interface{}, error) {
return base64.StdEncoding.EncodeToString(pk), nil
}
func (pk *PubKey) UnmarshalYAML(node *yaml.Node) error {
value := node.Value
ba, err := base64.StdEncoding.DecodeString(value)
if err != nil {
return err
}
*pk = ba
return nil
}
type A struct {
PublicKey PubKey `json:"PublicKey" yaml:"PublicKey"`
}
// No custom YAML codec
Coding/decoding goes like this:
func PublicKey() {
token := []byte{87, 88, 89, 90}
a := A{PublicKey: token}
fmt.Printf("A: % v\nA.PublicKey:%s\n\n", a, a.PublicKey)
out, _ := yaml.Marshal(a)
fmt.Println("Encoded: ", string(out))
var b A
err := yaml.Unmarshal(out, &b)
if err != nil {
println(err)
}
fmt.Printf("after decoding: % v\n", b)
}
Full example https://go.dev/play/p/2_gMi9sazIp
The result is:
A: {PublicKey:[87 88 89 90]}
A.PublicKey:WXYZ
Encoded: PublicKey: V1hZWg==
after decoding: {PublicKey:[87 88 89 90]}
BTW, base64 is how json
codec marshals byte slices
Example with your data: https://go.dev/play/p/dGr0i0DnnNX
A: {PublicKey:[87 88 89 90]}
A.PublicKey:WXYZ
Encoded JSON: {"PublicKey":"V1hZWg=="}
after decoding JSON: {PublicKey:[87 88 89 90]}