Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support tarantool serializable #46

Closed
delef opened this issue Jul 29, 2018 · 3 comments
Closed

Support tarantool serializable #46

delef opened this issue Jul 29, 2018 · 3 comments

Comments

@delef
Copy link

delef commented Jul 29, 2018

Tarantool send response as array of array (not hash), but I would like to mapping this response.
How can I get something like this?

class MessagePackPersonArray
  include MessagePack::Serializable
  include MessagePack::Serializable::Unmapped

  @[MessagePack::Field(key: 0)]
  property name : String
  
  @[MessagePack::Field(key: 1)]
  property age : Int32?
end

person = MessagePackPersonArray.from_msgpack(["John", 30, "1", 2, [1, 2, 3]].to_msgpack)
person.name.should eq("John")
person.age.should eq(30)

https://github.com/vladfaust/tarantool-crystal (use msgpack-crystal)

@kostya
Copy link
Collaborator

kostya commented Jul 29, 2018

I also think about doing compact mapping with arrays (sounds like protobuf format actually jeromegn/protobuf.cr#26), because packed data should be much smaller. Btw, it should be new Serializable module like SerializableCompact.

Until this not supported, you can do it like this (And also write macro that generate such code):

require "msgpack"

class MessagePackPersonArray
  def initialize(pull : MessagePack::Unpacker)
    token = pull.prefetch_token
    raise "expected array" unless token.type == :ARRAY

    size = token.size
    raise "expected array with size > 2" if size < 2
    token.used = true

    @name = String.new(pull)
    @age = Int32.new(pull)
    (size - 2).times { pull.skip_value }
  end
end

person = MessagePackPersonArray.from_msgpack(["John", 30, "1", 2, [1, 2, 3]].to_msgpack)
p person # => #<MessagePackPersonArray:0x102ef0e80 @name="John", @age=30>

@kostya
Copy link
Collaborator

kostya commented Jul 29, 2018

i add this in compact_serializable branch, you can read specs, about how it works https://github.com/crystal-community/msgpack-crystal/blob/compact_serializable/spec/compact_serializable_spec.cr

require "./src/msgpack"

class MessagePackPersonArray
  include MessagePack::CompactSerializable
  include MessagePack::CompactSerializable::Unmapped

  property name : String
  property age : Int32?
end

person = MessagePackPersonArray.from_msgpack(["John", 30, "1", 2, [1, 2, 3]].to_msgpack)
p person 
#=> #<MessagePackPersonArray:0x100aadea0 @msgpack_unmapped={2 => "1", 3 => 2_u8, 4 => [1_u8, 2_u8, 3_u8]}, @name="John", @age=30>

0, 1 it indexed by default, you can change it.

@kostya
Copy link
Collaborator

kostya commented Oct 6, 2019

ArraySerializable module in shard since v0.15

@kostya kostya closed this as completed Oct 6, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants