class Zenaton::Services::Serializer
Encoding and decoding ruby objects into Zenaton's json format
Constants
- ID_PREFIX
this string prefixs ids that are used to identify objects
- KEY_ARRAY
- KEY_DATA
- KEY_OBJECT
- KEY_OBJECT_NAME
- KEY_OBJECT_PROPERTIES
- KEY_STORE
Public Class Methods
new()
click to toggle source
# File lib/zenaton/services/serializer.rb, line 21 def initialize @properties = Properties.new end
Public Instance Methods
decode(json_string)
click to toggle source
Decodes Zenaton's format in a valid Ruby object
# File lib/zenaton/services/serializer.rb, line 43 def decode(json_string) parsed_json = JSON.parse(json_string) @decoded = [] @encoded = parsed_json.delete(KEY_STORE) case parsed_json.keys.first when KEY_DATA return parsed_json[KEY_DATA] when KEY_ARRAY return decode_enumerable(parsed_json[KEY_ARRAY]) when KEY_OBJECT id = parsed_json[KEY_OBJECT][ID_PREFIX.length..-1].to_i return decode_from_store(id, @encoded[id]) end end
encode(data)
click to toggle source
Encodes a given ruby object to Zenaton's json format
# File lib/zenaton/services/serializer.rb, line 28 def encode(data) @encoded = [] @decoded = [] value = {} raise ArgumentError, 'Procs cannot be serialized' if data.is_a?(Proc) if basic_type?(data) value[KEY_DATA] = data else value[KEY_OBJECT] = encode_to_store(data) end value[KEY_STORE] = @encoded value.to_json end
Private Instance Methods
basic_type?(data)
click to toggle source
rubocop:enable Metrics/MethodLength
# File lib/zenaton/services/serializer.rb, line 61 def basic_type?(data) data.is_a?(String) \ || data.is_a?(Integer) \ || data.is_a?(Float) \ || data.is_a?(TrueClass) \ || data.is_a?(FalseClass) \ || data.nil? end
decode_array(id, array)
click to toggle source
# File lib/zenaton/services/serializer.rb, line 166 def decode_array(id, array) @decoded[id] = object = [] object.concat(array.map(&method(:decode_element))) end
decode_element(value)
click to toggle source
rubocop:disable Metrics/MethodLength
# File lib/zenaton/services/serializer.rb, line 137 def decode_element(value) if store_id?(value) id = value[ID_PREFIX.length..-1].to_i encoded = @encoded[id] decode_from_store(id, encoded) elsif value.is_a?(Array) decode_legacy_array(value) elsif value.is_a?(Hash) decode_legacy_hash(value) else value end end
decode_enumerable(enumerable)
click to toggle source
rubocop:enable Metrics/MethodLength
# File lib/zenaton/services/serializer.rb, line 152 def decode_enumerable(enumerable) return decode_legacy_array(enumerable) if enumerable.is_a?(Array) return decode_legacy_hash(enumerable) if enumerable.is_a?(Hash) raise ArgumentError, 'Unknown type' end
decode_from_store(id, encoded)
click to toggle source
# File lib/zenaton/services/serializer.rb, line 179 def decode_from_store(id, encoded) decoded = @decoded[id] return decoded if decoded case encoded[KEY_ARRAY] when Array decode_array(id, encoded[KEY_ARRAY]) when Hash decode_hash(id, encoded[KEY_ARRAY]) else decode_object(id, encoded) end end
decode_hash(id, hash)
click to toggle source
# File lib/zenaton/services/serializer.rb, line 171 def decode_hash(id, hash) @decoded[id] = ActiveSupport::HashWithIndifferentAccess.new hash.each do |key, value| @decoded[id][key] = decode_element(value) end @decoded[id] end
decode_legacy_array(array)
click to toggle source
# File lib/zenaton/services/serializer.rb, line 158 def decode_legacy_array(array) array.map(&method(:decode_element)) end
decode_legacy_hash(hash)
click to toggle source
# File lib/zenaton/services/serializer.rb, line 162 def decode_legacy_hash(hash) transform_values(hash, &method(:decode_element)) end
decode_object(id, encoded_object)
click to toggle source
# File lib/zenaton/services/serializer.rb, line 204 def decode_object(id, encoded_object) object = @properties.blank_instance(encoded_object[KEY_OBJECT_NAME]) @decoded[id] = object properties = decode_legacy_hash(encoded_object[KEY_OBJECT_PROPERTIES]) @properties.set(object, properties) end
decoded_object_by_type(id, encoded)
click to toggle source
# File lib/zenaton/services/serializer.rb, line 192 def decoded_object_by_type(id, encoded) enumerable = encoded[KEY_ARRAY] case enumerable when Array decode_array(id, enumerable) when Hash decode_hash(id, enumerable) else decode_object(id, encoded) end end
encode_array(array)
click to toggle source
# File lib/zenaton/services/serializer.rb, line 114 def encode_array(array) { KEY_ARRAY => array.map(&method(:encode_value)) } end
encode_hash(hash)
click to toggle source
# File lib/zenaton/services/serializer.rb, line 120 def encode_hash(hash) { KEY_ARRAY => transform_values(hash, &method(:encode_value)) } end
encode_legacy_hash(hash)
click to toggle source
# File lib/zenaton/services/serializer.rb, line 126 def encode_legacy_hash(hash) transform_values(hash, &method(:encode_value)) end
encode_object(object)
click to toggle source
# File lib/zenaton/services/serializer.rb, line 107 def encode_object(object) { KEY_OBJECT_NAME => object.class.name, KEY_OBJECT_PROPERTIES => encode_legacy_hash(@properties.from(object)) } end
encode_to_store(object)
click to toggle source
# File lib/zenaton/services/serializer.rb, line 79 def encode_to_store(object) id = @decoded.index { |decoded| decoded.object_id == object.object_id } return store_id(id) if id store_and_encode(object) end
encode_value(value)
click to toggle source
# File lib/zenaton/services/serializer.rb, line 70 def encode_value(value) raise ArgumentError, 'Procs cannot be serialized' if value.is_a?(Proc) if basic_type?(value) value else encode_to_store(value) end end
encoded_object_by_type(object)
click to toggle source
# File lib/zenaton/services/serializer.rb, line 96 def encoded_object_by_type(object) case object when Array encode_array(object) when Hash encode_hash(object) else encode_object(object) end end
store_and_encode(object)
click to toggle source
# File lib/zenaton/services/serializer.rb, line 85 def store_and_encode(object) id = @decoded.length @decoded[id] = object @encoded[id] = encoded_object_by_type(object) store_id(id) end
store_id(id)
click to toggle source
# File lib/zenaton/services/serializer.rb, line 92 def store_id(id) "#{ID_PREFIX}#{id}" end
store_id?(string)
click to toggle source
# File lib/zenaton/services/serializer.rb, line 130 def store_id?(string) string.is_a?(String) \ && string.start_with?(ID_PREFIX) \ && string[ID_PREFIX.length..-1].to_i <= @encoded.length end
transform_values(hash) { |v| ... }
click to toggle source
# File lib/zenaton/services/serializer.rb, line 211 def transform_values(hash) hash.each_with_object({}) do |(k, v), acc| acc[k] = yield(v) end end