aboutsummaryrefslogtreecommitdiffstats
path: root/activejob/lib/active_job/serializers
diff options
context:
space:
mode:
Diffstat (limited to 'activejob/lib/active_job/serializers')
-rw-r--r--activejob/lib/active_job/serializers/array_serializer.rb26
-rw-r--r--activejob/lib/active_job/serializers/base_serializer.rb13
-rw-r--r--activejob/lib/active_job/serializers/class_serializer.rb24
-rw-r--r--activejob/lib/active_job/serializers/duration_serializer.rb42
-rw-r--r--activejob/lib/active_job/serializers/global_id_serializer.rb32
-rw-r--r--activejob/lib/active_job/serializers/hash_serializer.rb62
-rw-r--r--activejob/lib/active_job/serializers/hash_with_indifferent_access_serializer.rb37
-rw-r--r--activejob/lib/active_job/serializers/object_serializer.rb27
-rw-r--r--activejob/lib/active_job/serializers/standard_type_serializer.rb26
-rw-r--r--activejob/lib/active_job/serializers/struct_serializer.rb38
-rw-r--r--activejob/lib/active_job/serializers/symbol_serializer.rb28
11 files changed, 355 insertions, 0 deletions
diff --git a/activejob/lib/active_job/serializers/array_serializer.rb b/activejob/lib/active_job/serializers/array_serializer.rb
new file mode 100644
index 0000000000..f0254f4488
--- /dev/null
+++ b/activejob/lib/active_job/serializers/array_serializer.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+module ActiveJob
+ module Serializers
+ # Provides methods to serialize and deserialize `Array`
+ class ArraySerializer < BaseSerializer
+ class << self
+ alias_method :deserialize?, :serialize?
+
+ def serialize(array)
+ array.map { |arg| ::ActiveJob::Serializers.serialize(arg) }
+ end
+
+ def deserialize(array)
+ array.map { |arg| ::ActiveJob::Serializers.deserialize(arg) }
+ end
+
+ private
+
+ def klass
+ ::Array
+ end
+ end
+ end
+ end
+end
diff --git a/activejob/lib/active_job/serializers/base_serializer.rb b/activejob/lib/active_job/serializers/base_serializer.rb
new file mode 100644
index 0000000000..98f7852fd6
--- /dev/null
+++ b/activejob/lib/active_job/serializers/base_serializer.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module ActiveJob
+ module Serializers
+ class BaseSerializer
+ class << self
+ def serialize?(argument)
+ argument.is_a?(klass)
+ end
+ end
+ end
+ end
+end
diff --git a/activejob/lib/active_job/serializers/class_serializer.rb b/activejob/lib/active_job/serializers/class_serializer.rb
new file mode 100644
index 0000000000..d36e8c0ebc
--- /dev/null
+++ b/activejob/lib/active_job/serializers/class_serializer.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module ActiveJob
+ module Serializers
+ # Provides methods to serialize and deserialize `Class` (`ActiveRecord::Base`, `MySpecialService`, ...)
+ class ClassSerializer < ObjectSerializer
+ class << self
+ def serialize(argument_klass)
+ { key => "::#{argument_klass.name}" }
+ end
+
+ def key
+ "_aj_class"
+ end
+
+ private
+
+ def klass
+ ::Class
+ end
+ end
+ end
+ end
+end
diff --git a/activejob/lib/active_job/serializers/duration_serializer.rb b/activejob/lib/active_job/serializers/duration_serializer.rb
new file mode 100644
index 0000000000..72b7b9528a
--- /dev/null
+++ b/activejob/lib/active_job/serializers/duration_serializer.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+module ActiveJob
+ module Serializers
+ # Provides methods to serialize and deserialize `ActiveSupport::Duration` (`1.day`, `2.weeks`, ...)
+ class DurationSerializer < ObjectSerializer
+ class << self
+ def serialize(duration)
+ {
+ key => duration.value,
+ parts_key => ::ActiveJob::Serializers.serialize(duration.parts)
+ }
+ end
+
+ def deserialize(hash)
+ value = hash[key]
+ parts = ::ActiveJob::Serializers.deserialize(hash[parts_key])
+
+ klass.new(value, parts)
+ end
+
+ def key
+ "_aj_activesupport_duration"
+ end
+
+ private
+
+ def klass
+ ::ActiveSupport::Duration
+ end
+
+ def keys
+ super.push parts_key
+ end
+
+ def parts_key
+ "parts"
+ end
+ end
+ end
+ end
+end
diff --git a/activejob/lib/active_job/serializers/global_id_serializer.rb b/activejob/lib/active_job/serializers/global_id_serializer.rb
new file mode 100644
index 0000000000..1961e43fca
--- /dev/null
+++ b/activejob/lib/active_job/serializers/global_id_serializer.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+module ActiveJob
+ module Serializers
+ # Provides methods to serialize and deserialize objects which mixes `GlobalID::Identification`,
+ # including `ActiveRecord::Base` models
+ class GlobalIDSerializer < ObjectSerializer
+ class << self
+ def serialize(object)
+ { 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[key])
+ end
+
+ def key
+ "_aj_globalid"
+ end
+
+ private
+
+ def klass
+ ::GlobalID::Identification
+ end
+ end
+ end
+ end
+end
diff --git a/activejob/lib/active_job/serializers/hash_serializer.rb b/activejob/lib/active_job/serializers/hash_serializer.rb
new file mode 100644
index 0000000000..eee081de7c
--- /dev/null
+++ b/activejob/lib/active_job/serializers/hash_serializer.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+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
+
+ def deserialize?(argument)
+ argument.is_a?(Hash) && argument[key]
+ end
+
+ def deserialize(hash)
+ result = hash.transform_values { |v| ::ActiveJob::Serializers::deserialize(v) }
+ symbol_keys = result.delete(key)
+ transform_symbol_keys(result, symbol_keys)
+ end
+
+ def key
+ "_aj_symbol_keys"
+ end
+
+ private
+
+ def serialize_hash(hash)
+ hash.each_with_object({}) do |(key, value), result|
+ result[serialize_hash_key(key)] = ::ActiveJob::Serializers.serialize(value)
+ end
+ end
+
+ def serialize_hash_key(key)
+ raise SerializationError.new("Only string and symbol hash keys may be serialized as job arguments, but #{key.inspect} is a #{key.class}") unless [String, Symbol].include?(key.class)
+
+ raise SerializationError.new("Can't serialize a Hash with reserved key #{key.inspect}") if ActiveJob::Base.reserved_serializers_keys.include?(key.to_s)
+
+ key.to_s
+ end
+
+ def transform_symbol_keys(hash, symbol_keys)
+ hash.transform_keys do |key|
+ if symbol_keys.include?(key)
+ key.to_sym
+ else
+ key
+ end
+ end
+ end
+
+ def klass
+ ::Hash
+ end
+ end
+ end
+ end
+end
diff --git a/activejob/lib/active_job/serializers/hash_with_indifferent_access_serializer.rb b/activejob/lib/active_job/serializers/hash_with_indifferent_access_serializer.rb
new file mode 100644
index 0000000000..50e80757cd
--- /dev/null
+++ b/activejob/lib/active_job/serializers/hash_with_indifferent_access_serializer.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+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] = ::ActiveJob::Serializers.serialize(true)
+ result
+ end
+
+ def deserialize?(argument)
+ argument.is_a?(Hash) && argument[key]
+ end
+
+ def deserialize(hash)
+ result = hash.transform_values { |v| ::ActiveJob::Serializers.deserialize(v) }
+ result.delete(key)
+ result.with_indifferent_access
+ end
+
+ def key
+ "_aj_hash_with_indifferent_access"
+ end
+
+ private
+
+ def klass
+ ::ActiveSupport::HashWithIndifferentAccess
+ end
+ end
+ end
+ end
+end
diff --git a/activejob/lib/active_job/serializers/object_serializer.rb b/activejob/lib/active_job/serializers/object_serializer.rb
new file mode 100644
index 0000000000..075360b26e
--- /dev/null
+++ b/activejob/lib/active_job/serializers/object_serializer.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module ActiveJob
+ module Serializers
+ class ObjectSerializer < BaseSerializer
+ class << self
+ def serialize(object)
+ { key => object.class.name }
+ end
+
+ def deserialize?(argument)
+ argument.respond_to?(:keys) && argument.keys == keys
+ end
+
+ def deserialize(hash)
+ hash[key].constantize
+ end
+
+ private
+
+ def keys
+ [key]
+ end
+ end
+ end
+ end
+end
diff --git a/activejob/lib/active_job/serializers/standard_type_serializer.rb b/activejob/lib/active_job/serializers/standard_type_serializer.rb
new file mode 100644
index 0000000000..8969b31d6b
--- /dev/null
+++ b/activejob/lib/active_job/serializers/standard_type_serializer.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+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)
+ ::ActiveJob::Arguments::TYPE_WHITELIST.include? argument.class
+ end
+
+ def serialize(argument)
+ argument
+ end
+
+ alias_method :deserialize?, :serialize?
+
+ def deserialize(argument)
+ object = GlobalID::Locator.locate(argument) if argument.is_a? String
+ object || argument
+ end
+ end
+ end
+ end
+end
diff --git a/activejob/lib/active_job/serializers/struct_serializer.rb b/activejob/lib/active_job/serializers/struct_serializer.rb
new file mode 100644
index 0000000000..f6791611ed
--- /dev/null
+++ b/activejob/lib/active_job/serializers/struct_serializer.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+module ActiveJob
+ module Serializers
+ # Provides methods to serialize and deserialize struct instances
+ # (`Struct.new('Rectangle', :width, :height).new(12, 20)`)
+ class StructSerializer < ObjectSerializer
+ class << self
+ def serialize(object)
+ super.merge values_key => ::ActiveJob::Serializers.serialize(object.values)
+ end
+
+ def deserialize(hash)
+ values = ::ActiveJob::Serializers.deserialize(hash[values_key])
+ super.new(*values)
+ end
+
+ def key
+ "_aj_struct"
+ end
+
+ private
+
+ def klass
+ ::Struct
+ end
+
+ def keys
+ super.push values_key
+ end
+
+ def values_key
+ "values"
+ end
+ end
+ end
+ end
+end
diff --git a/activejob/lib/active_job/serializers/symbol_serializer.rb b/activejob/lib/active_job/serializers/symbol_serializer.rb
new file mode 100644
index 0000000000..f128ae8284
--- /dev/null
+++ b/activejob/lib/active_job/serializers/symbol_serializer.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+module ActiveJob
+ module Serializers
+ # Provides methods to serialize and deserialize `Symbol` (`:foo`, `:bar`, ...)
+ class SymbolSerializer < ObjectSerializer
+ class << self
+ def serialize(symbol)
+ { key => symbol.to_s }
+ end
+
+ def deserialize(hash)
+ hash[key].to_sym
+ end
+
+ def key
+ "_aj_symbol"
+ end
+
+ private
+
+ def klass
+ ::Symbol
+ end
+ end
+ end
+ end
+end