crystal-community / msgpack-crystal

MessagePack implementation in Crystal msgpack.org[Crystal]
136 stars 18 forks source link

Support for nested Hash #33

Closed bararchy closed 7 years ago

bararchy commented 7 years ago

Can we add support to pack and unpack

Hash(String, Hash(Symbol, (Int32 | String | MyClass)))

etc..

benoist commented 7 years ago

Currently it should work with nested hashes as long as you use the primitive types known to message pack. Symbol and MyClass are not known.

You would have to create a new class with mapping defined in the class. https://github.com/benoist/msgpack-crystal/blob/master/src/message_pack/mapping.cr

However the Union type with a custom class is difficult to do, as you might get the following problem:

class MyHash
  MessagePack.mapping({
    hash: Hash(Symbol, (Int32 | String | MyClass))
  })
end

class MyClass
  MessagePack.mapping({
    my_string: String
  })
end

{ 
  "string" => MyHash.new({ 
    :symbol1 => "string", 
    :symbol2 => MyClass.new("class string") 
  })
}.to_msgpack

It will create a message packed buffer something like this (its missing a few bits but I left it out so its more readable)

[ :hash_start, :string, "string", :hash_start, :string, "symbol1", :string, "string", :string, "symbol2", :string, "class string"]

When you want to unpack it and gets to the symbol2 value, it doesn't know it should be of type MyClass. The only way to do this would be to use message pack extensions, which requires you to define the extension types yourself.

This is currently not supported.

bararchy commented 7 years ago

@benoist Thanks :) That helped.