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

Custom serializers #19

Merged
merged 9 commits into from
Sep 10, 2018
Merged

Custom serializers #19

merged 9 commits into from
Sep 10, 2018

Conversation

robacarp
Copy link
Collaborator

@robacarp robacarp commented Sep 10, 2018

This replaces the attempt at a general purpose (de)serializer by case statement with an extensible, customize-able, method based approach.

sort of fixes #16

This opens the door for a wider variety of orms and other object storage mechanisms to easily implement serialization, which will make fixing issues like #15 #14 much easier.

Custom serializers (or serializer overrides) are implemented by defining a pair of methods on a job called serialize_<type>. For example, the methods which handle Int32 are:

def serialize_int32(value : Int32) : String
  value.to_s
end

def deserialize_int32(raw : String) : Int32?
  if raw
    raw.to_i32
  end
end

These methods are declared in the abstract Job class, which means that they're override-able too, to your hearts content:

class PutsJob < Mosquito::QueuedJob
   params(count : Int32 | Nil)

  def perform
    count.times { puts "puts job" }
  end

  def deserialize_int32(raw : String) : Int32
    puts "custom deserialization, with a default value!"
    if raw
      raw.to_i32
    else
      0
    end
  end
end

Serializing ORM models gets a little more complicated, but I think this will be a better abstraction. To match the current functionality, I'm including a Serializers::Granite module, which provides a macro to generate serializers for model classes. It's used like this:

class PutsJob < Mosquito::QueuedJob
  include Mosquito::Serializers::Granite

  params(user : User | Nil)

  serialize_granite_model User

  def perform
    puts "Hello user #{user.id}"
  end
end

serialize_granite_model(User) generates these methods:

def serialize_user(model : User) : String
  model.id.to_s
end

def deserialize_user(raw : String) : User
  id = raw.to_i
  User.find id
end

@robacarp robacarp merged commit f3a23d4 into master Sep 10, 2018
@robacarp robacarp deleted the custom_serializers branch September 10, 2018 22:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

Expected a parameter named courier but found nil instead.
1 participant