ugorji / go

idiomatic codec and rpc lib for msgpack, cbor, json, etc. msgpack.org[Go]
MIT License
1.87k stars 295 forks source link

NullTime goes valid, comes as not valid [msgpack] #91

Closed ferhatelmas closed 9 years ago

ferhatelmas commented 9 years ago
var out []byte
var nt agtime.Time
msgpack := codec.MsgpackHandle{}
t := agtime.Time{Time: time.Now(), Valid: true}
spew.Dump(t)
codec.NewEncoderBytes(&out, &msgpack).Encode(t)
codec.NewDecoderBytes(out, &msgpack).Decode(&nt)
spew.Dump(nt)
(agtime.Time) {
 Time: (time.Time) 2015-08-14 17:21:53.383904263 +0200 CEST,
 Valid: (bool) true
}
(agtime.Time) {
 Time: (time.Time) 2015-08-14 17:21:53.383904263 +0200 CEST,
 Valid: (bool) false
}

Time struct:

type Time struct {
    time.Time
    Valid bool
}

If Time struct was defined as following then it works:

type Time struct {
    Time  time.Time
    Valid bool
}

Thanks!

ugorji commented 9 years ago

I was stumped on this at first, but did some debugging, and see it is working as designed, unfortunately.

I first tried the experiment with encoding/json in the standard library, and saw the exact same results (as in this defect).

The reason is that, when you embed a value, it inherits methods of the anonymous field. Consequently, agtime.Time embeds time.Time and consequently inherits the (M|Unm)arshal(Text|Binary) methods.

Thus, that method is called when encoding or decoding. That is why the implementation method of the embedded time.Time is called. Unfortunately, there isn't a way to get only methods directly on a type: you can only get (via reflection) all the methods on the method_set (which includes methods inherited via embedding, etc). So, even if we wanted to change the implementation to "ignore" inherited methods from anonymous fields, we can't.

It's a bummer :(

ferhatelmas commented 9 years ago

I see so we need to provide relevant (M|Unm)arshal(Text|Binary) and Gob(En|De)code methods if we embed types that provide these methods.

Thanks for explanation, it works after writing a custom one to override provided.