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:
|
if typ.Implements(binaryUnmarshalerType) { |
|
return nilAwareDecoder(typ, unmarshalBinaryValue) |
|
} |
|
if typ.Implements(textUnmarshalerType) { |
|
return nilAwareDecoder(typ, unmarshalTextValue) |
|
} |
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)
}
Expected Behavior
msgpacksuccessfully unmarshals a type implementing bothencoding.TextUnmarshalerandencoding.BinaryUnmashalerusing the former interface when the data is of astrformat, and is stored in text representation.Current Behavior
msgpackfails 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
BinaryUnmarshalerunconditionally:msgpack/decode_value.go
Lines 73 to 78 in 19c91df
Possible Solution
Choose the preferred unmarshalling interface based on MessagePack format (MessagePack has distinct
strandbinformats), preferringTextUnmarshalerwhen it's anstr.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