msgpack
msgpack copied to clipboard
Use encoding.TextUnmarshaler when MessagePack format is a str
Expected Behavior
msgpack
successfully unmarshals a type implementing both encoding.TextUnmarshaler
and encoding.BinaryUnmashaler
using the former interface when the data is of a str
format, and is stored in text representation.
Current Behavior
msgpack
fails to unmarshal the data in aforementioned conditions, because it's using the latter interface which does not expect text data.
This is because the library prefers BinaryUnmarshaler
unconditionally:
https://github.com/vmihailenco/msgpack/blob/19c91dfdfa062658c39d9321be26163fc5833bd1/decode_value.go#L73-L78
Possible Solution
Choose the preferred unmarshalling interface based on MessagePack format (MessagePack has distinct str
and bin
formats), preferring TextUnmarshaler
when it's an str
.
Steps to Reproduce
This example might look arbitrary out of context, but this situation easily arises when round-tripping the data through JSON and/or other libraries (especially in dynamically typed programming languages).
https://play.golang.com/p/3WFWbPVKDkp
package main
import (
"log"
"github.com/gofrs/uuid/v5"
"github.com/vmihailenco/msgpack/v5"
)
type T struct {
ID uuid.UUID
}
func main() {
obj := map[string]any{
"ID": "29247b08-ead7-46b3-b263-6944c2096673",
}
b, err := msgpack.Marshal(obj)
if err != nil {
panic(err)
}
var t T
err = msgpack.Unmarshal(b, &t)
if err != nil {
panic(err)
}
log.Printf("%#v", t)
}