go-restruct / restruct

Rich binary (de)serialization library for Golang
https://restruct.io/
ISC License
360 stars 17 forks source link

Packing struct with interfaces #39

Closed klaxxon closed 4 years ago

klaxxon commented 4 years ago

Unpack works great, thanks! Now, for testing sending the Unpacked struct back through the Pack to verify the output was the same as the binary input.

Been all through the Googleverse and have been muddling with the code to try to get it to traverse and interface in a struct.

type Test struct { MessageType byte Message interface{} }

It has already been through the Unpack process so "Message" points to a valid struct, but the Pack routine uses f.Elem() (v.Elem() or course works in write) which is statically typed to the original "interface{}" type so it knows nothing about what the value is pointed to at the moment. I think I may need to add something to dynamically build the cache when an interface is encountered.?.?

Thanks again!

klaxxon commented 4 years ago

I think I found the issue. The package expects everything to be defined so it can determine the size of the buffer when the initial interface is passed into Pack. This is not an issue, it was not designed to support this.

Thanks

jchv commented 4 years ago

Hey sorry.

You can in fact do a type switch with Restruct, but you will probably need to implement it manually on the type individually. For example, you can override the size behavior by implementing restruct.BitSizer on your types, which may be enough if you just want packing. If you also want unpacking you'll need to implement the type switch manually by writing an restruct.Unpacker implementation as well.

There's a lot of different ways to approach this. I generally implement type switches by having a map from the key to an instance of the type i want (stored as interface{}, so the map is map[byte]interface{}) and in my unpacker/sizer implementations I can use reflection to get the concrete type and instantiate a new one, which can then be used with restruct.Unpack or restruct.BitSize.

I can produce an example if needed. I'm talking from memory so some of the details are fuzzy in abstract, sorry!