Allow serializers to be used either as classes or objects

上级 b098584f
......@@ -3,24 +3,22 @@
module ActiveJob
module Serializers
# Provides methods to serialize and deserialize `Array`
class ArraySerializer < BaseSerializer
class << self
alias_method :deserialize?, :serialize?
class ArraySerializer < BaseSerializer # :nodoc:
alias_method :deserialize?, :serialize?
def serialize(array)
array.map { |arg| Serializers.serialize(arg) }
end
def serialize(array)
array.map { |arg| Serializers.serialize(arg) }
end
def deserialize(array)
array.map { |arg| Serializers.deserialize(arg) }
end
def deserialize(array)
array.map { |arg| Serializers.deserialize(arg) }
end
private
private
def klass
Array
end
end
end
end
end
......@@ -3,29 +3,33 @@
module ActiveJob
module Serializers
class BaseSerializer
include Singleton
class << self
def serialize?(argument)
argument.is_a?(klass)
end
delegate :serialize?, :deserialize?, :serialize, :deserialize, to: :instance
end
def deserialize?(_argument)
raise NotImplementedError
end
def serialize?(argument)
argument.is_a?(klass)
end
def serialize(_argument)
raise NotImplementedError
end
def deserialize?(_argument)
raise NotImplementedError
end
def deserialize(_argument)
raise NotImplementedError
end
def serialize(_argument)
raise NotImplementedError
end
private
def deserialize(_argument)
raise NotImplementedError
end
protected
def klass
raise NotImplementedError
end
end
end
end
end
module ActiveJob
module Serializers
class DurationSerializer < ObjectSerializer
class << self
def serialize(duration)
super("value" => duration.value, "parts" => Serializers.serialize(duration.parts))
end
class DurationSerializer < ObjectSerializer # :nodoc:
def serialize(duration)
super("value" => duration.value, "parts" => Serializers.serialize(duration.parts))
end
def deserialize(hash)
value = hash["value"]
parts = Serializers.deserialize(hash["parts"])
def deserialize(hash)
value = hash["value"]
parts = Serializers.deserialize(hash["parts"])
klass.new(value, parts)
end
klass.new(value, parts)
end
private
private
def klass
ActiveSupport::Duration
end
end
end
end
end
......@@ -4,29 +4,27 @@ module ActiveJob
module Serializers
# Provides methods to serialize and deserialize objects which mixes `GlobalID::Identification`,
# including `ActiveRecord::Base` models
class GlobalIDSerializer < BaseSerializer
class << self
def serialize(object)
{ GLOBALID_KEY => object.to_global_id.to_s }
rescue URI::GID::MissingModelIdError
raise SerializationError, "Unable to serialize #{object.class} " \
"without an id. (Maybe you forgot to call save?)"
end
class GlobalIDSerializer < BaseSerializer # :nodoc:
def serialize(object)
{ GLOBALID_KEY => object.to_global_id.to_s }
rescue URI::GID::MissingModelIdError
raise SerializationError, "Unable to serialize #{object.class} " \
"without an id. (Maybe you forgot to call save?)"
end
def deserialize(hash)
GlobalID::Locator.locate(hash[GLOBALID_KEY])
end
def deserialize(hash)
GlobalID::Locator.locate(hash[GLOBALID_KEY])
end
def deserialize?(argument)
argument.is_a?(Hash) && argument[GLOBALID_KEY]
end
def deserialize?(argument)
argument.is_a?(Hash) && argument[GLOBALID_KEY]
end
private
private
def klass
GlobalID::Identification
end
end
end
end
end
......@@ -4,26 +4,25 @@ module ActiveJob
module Serializers
# Provides methods to serialize and deserialize `Hash` (`{key: field, ...}`)
# Only `String` or `Symbol` can be used as a key. Values will be serialized by known serializers
class HashSerializer < BaseSerializer
class << self
def serialize(hash)
symbol_keys = hash.each_key.grep(Symbol).map(&:to_s)
result = serialize_hash(hash)
result[key] = symbol_keys
result
end
class HashSerializer < BaseSerializer # :nodoc:
def serialize(hash)
symbol_keys = hash.each_key.grep(Symbol).map(&:to_s)
result = serialize_hash(hash)
result[key] = symbol_keys
result
end
def deserialize?(argument)
argument.is_a?(Hash) && argument[key]
end
def deserialize?(argument)
argument.is_a?(Hash) && argument[key]
end
def deserialize(hash)
result = hash.transform_values { |v| Serializers::deserialize(v) }
symbol_keys = result.delete(key)
transform_symbol_keys(result, symbol_keys)
end
def deserialize(hash)
result = hash.transform_values { |v| Serializers::deserialize(v) }
symbol_keys = result.delete(key)
transform_symbol_keys(result, symbol_keys)
end
private
private
def key
SYMBOL_KEYS_KEY
......@@ -56,7 +55,6 @@ def transform_symbol_keys(hash, symbol_keys)
def klass
Hash
end
end
end
end
end
......@@ -4,21 +4,20 @@ module ActiveJob
module Serializers
# Provides methods to serialize and deserialize `ActiveSupport::HashWithIndifferentAccess`
# Values will be serialized by known serializers
class HashWithIndifferentAccessSerializer < HashSerializer
class << self
def serialize(hash)
result = serialize_hash(hash)
result[key] = Serializers.serialize(true)
result
end
class HashWithIndifferentAccessSerializer < HashSerializer # :nodoc:
def serialize(hash)
result = serialize_hash(hash)
result[key] = Serializers.serialize(true)
result
end
def deserialize(hash)
result = hash.transform_values { |v| Serializers.deserialize(v) }
result.delete(key)
result.with_indifferent_access
end
def deserialize(hash)
result = hash.transform_values { |v| Serializers.deserialize(v) }
result.delete(key)
result.with_indifferent_access
end
private
private
def key
WITH_INDIFFERENT_ACCESS_KEY
......@@ -27,7 +26,6 @@ def key
def klass
ActiveSupport::HashWithIndifferentAccess
end
end
end
end
end
......@@ -3,14 +3,12 @@
module ActiveJob
module Serializers
class ObjectSerializer < BaseSerializer
class << self
def serialize(hash)
{ OBJECT_SERIALIZER_KEY => self.name }.merge!(hash)
end
def serialize(hash)
{ OBJECT_SERIALIZER_KEY => self.class.name }.merge!(hash)
end
def deserialize?(argument)
argument.is_a?(Hash) && argument[OBJECT_SERIALIZER_KEY] == self.name
end
def deserialize?(argument)
argument.is_a?(Hash) && argument[OBJECT_SERIALIZER_KEY] == self.class.name
end
end
end
......
......@@ -4,22 +4,20 @@ module ActiveJob
module Serializers
# Provides methods to serialize and deserialize standard types
# (`NilClass`, `String`, `Integer`, `Fixnum`, `Bignum`, `Float`, `BigDecimal`, `TrueClass`, `FalseClass`)
class StandardTypeSerializer < BaseSerializer
class << self
def serialize?(argument)
Arguments::TYPE_WHITELIST.include? argument.class
end
class StandardTypeSerializer < BaseSerializer # :nodoc:
def serialize?(argument)
Arguments::TYPE_WHITELIST.include? argument.class
end
def serialize(argument)
argument
end
def serialize(argument)
argument
end
alias_method :deserialize?, :serialize?
alias_method :deserialize?, :serialize?
def deserialize(argument)
object = GlobalID::Locator.locate(argument) if argument.is_a? String
object || argument
end
def deserialize(argument)
object = GlobalID::Locator.locate(argument) if argument.is_a? String
object || argument
end
end
end
......
module ActiveJob
module Serializers
class SymbolSerializer < ObjectSerializer
class << self
def serialize(argument)
super("value" => argument.to_s)
end
class SymbolSerializer < ObjectSerializer # :nodoc:
def serialize(argument)
super("value" => argument.to_s)
end
def deserialize(argument)
argument["value"].to_sym
end
def deserialize(argument)
argument["value"].to_sym
end
private
private
def klass
Symbol
end
end
end
end
end
......@@ -17,21 +17,19 @@ def ==(other)
end
class DummySerializer < ActiveJob::Serializers::ObjectSerializer
class << self
def serialize(object)
super({ "value" => object.value })
end
def serialize(object)
super({ "value" => object.value })
end
def deserialize(hash)
DummyValueObject.new(hash["value"])
end
def deserialize(hash)
DummyValueObject.new(hash["value"])
end
private
private
def klass
DummyValueObject
end
end
end
setup do
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册