msgpack
msgpack copied to clipboard
Types with pointer receivers that are not pointers cause do not encode
If you try to encode a type with pointer receivers on the type, but is not a pointer, you get an error:
msgpack: Encode(non-addressable main.Operation)
So, for example:
type Operation uint16
func (o *Operation) MarshalMsgpack() ([]byte, error) {
return msgpack.Marshal(o)
}
func (o *Operation) UnmarshalMsgpack(b []byte) error {
return msgpack.Unmarshal(b, o)
}
You cannot use mgspack.Marshal(Operation(1)).
Now, if you change MarshalMsgpack() to have a value receiver instead, this works:
func (o Operation) MarshalMsgpack() ([]byte, error) {
return msgpack.Marshal(o)
}
Without the pointer, this will encode fine. This is in version v4 and v5. I'm currently using v4 due to the other issues I have reported in the previous weeks.
Here are some playgrounds:
https://go.dev/play/p/fVySSbkpz93 -- does not work https://go.dev/play/p/0zeobarO3fD -- works because I made it a value receiver
Expected Behavior
Should encode with no error.
Current Behavior
msgpack: Encode(non-addressable main.Operation)
Possible Solution
This is some type of tricky reflection problem. My guess is that you have to do something like:
reflect.ValueOf(v).Addr()
Then you can probably work on it.
The most definitive work around reflection decoding that would mirror what you are doing: https://github.com/go-json-experiment/json
Steps to Reproduce
https://go.dev/play/p/fVySSbkpz93 -- does not work https://go.dev/play/p/0zeobarO3fD -- works because I made it a value receiver
Context (Environment)
It makes it so that you have a type that can't fit into interfaces with all methods. For me, this affected some testing stuff, but I found clever (aka confusing for maintainers) way around the problem.