class SimplySerializable::Serializer

Attributes

attributes[R]
do_not_serialize_if_class_is[R]
except[R]
object[R]
only[R]

Public Class Methods

new( attributes: [], cache: {}, do_not_serialize_if_class_is: [], except: nil, include_readable_instance_variables: true, method_prefix: :serialize, object:, only: nil ) click to toggle source
# File lib/simply_serializable/serializer.rb, line 11
def initialize(
  attributes: [],
  cache: {},
  do_not_serialize_if_class_is: [],
  except: nil,
  include_readable_instance_variables: true,
  method_prefix: :serialize,
  object:,
  only: nil
)
  @object = object
  @id = id
  @attributes = attributes
  @do_not_serialize_if_class_is = do_not_serialize_if_class_is || []
  @do_not_serialize_if_class_is = [@do_not_serialize_if_class_is] unless @do_not_serialize_if_class_is.is_a?(Array)
  @include_readable_instance_variables = include_readable_instance_variables
  @except = except&.map(&:to_sym)
  @only = only&.map(&:to_sym)
  @method_prefix = method_prefix
  @local_cache = cache
  @local_cache[cache_key] = nil

  populate_attributes
end

Public Instance Methods

cache() click to toggle source
# File lib/simply_serializable/serializer.rb, line 36
def cache
  @cache ||= begin
    serialize
    @local_cache
  end
end
id() click to toggle source
# File lib/simply_serializable/serializer.rb, line 43
def id
  @id ||= cache_key
end
nestable?() click to toggle source
# File lib/simply_serializable/serializer.rb, line 47
def nestable?
  return @nestable unless @nestable.nil?

  serialize
  @nestable
end
nested() click to toggle source
# File lib/simply_serializable/serializer.rb, line 54
def nested
  @nested ||= begin
    deep_nest(serialize[:root])
  end
end
serialize() click to toggle source
# File lib/simply_serializable/serializer.rb, line 60
def serialize
  @serialize ||= begin
    @nestable = true
    ret = deep_serialize(object_value_hash)

    @local_cache[cache_key] = {
      id: cache_key,
      object: object.class.name,
      fingeprint: fingerprint,
      data: ret
    }

    {
      root: cache_key,
      objects: @local_cache
    }
  end
end
to_s() click to toggle source
# File lib/simply_serializable/serializer.rb, line 79
def to_s
  @to_s ||= serialize.to_s
end

Private Instance Methods

cache_key() click to toggle source
# File lib/simply_serializable/serializer.rb, line 85
def cache_key
  @cache_key ||= cache_key_for(object)
end
cache_key_for(obj) click to toggle source
# File lib/simply_serializable/serializer.rb, line 89
def cache_key_for(obj)
  "#{obj.class.name}/#{fingerprint_for(obj)}"
end
deep_nest(obj_id) click to toggle source
# File lib/simply_serializable/serializer.rb, line 93
def deep_nest(obj_id)
  raise Error::CircularDependencyError unless @nestable

  Hash[@local_cache[obj_id][:data].map do |k, v|
    v = deep_nest(v.dig(:id)) if v.is_a?(Hash) && v.dig(:object) == :reference
    [k, v]
  end]
end
deep_serialize(obj) click to toggle source
# File lib/simply_serializable/serializer.rb, line 102
def deep_serialize(obj)
  case obj
  when *do_not_serialize_if_class_is
    obj
  when FalseClass, Float, nil, Integer, String, Symbol, TrueClass
    obj
  when Array
    obj.map { |v| deep_serialize(v) }
  when Hash
    Hash[obj.map { |k, v| [deep_serialize(k), deep_serialize(v)] }]
  when Module
    obj.name
  else
    serialize_object(obj)
  end
end
fingerprint() click to toggle source
# File lib/simply_serializable/serializer.rb, line 119
def fingerprint
  @fingerprint ||= fingerprint_for(object)
end
fingerprint_for(obj) click to toggle source
# File lib/simply_serializable/serializer.rb, line 123
def fingerprint_for(obj)
  if obj.respond_to?(:fingerprint)
    obj.fingerprint
  else
    Fingerprintable::Fingerprinter.new(object: obj).fingerprint
  end
end
instance_vars_with_readers() click to toggle source
# File lib/simply_serializable/serializer.rb, line 131
def instance_vars_with_readers
  instance_variables = Hash[object.instance_variables.map { |e| [e, 1] }]
  ret = object.class.instance_methods.select do |method|
    instance_variables.key?("@#{method}".to_sym)
  end
  ret.map(&:to_sym)
end
method_for_attribute(attr) click to toggle source
# File lib/simply_serializable/serializer.rb, line 139
def method_for_attribute(attr)
  if object.class.instance_methods.include?("#{@method_prefix}_#{attr}".to_sym)
    "#{@method_prefix}_#{attr}"
  else
    attr
  end
end
object_value_hash() click to toggle source
# File lib/simply_serializable/serializer.rb, line 147
def object_value_hash
  Hash[attributes.map do |attr|
    [attr, object.send(method_for_attribute(attr))]
  end]
end
populate_attributes() click to toggle source
# File lib/simply_serializable/serializer.rb, line 153
def populate_attributes
  raise 'You cannot pass only and except values.  Please choose one.' if !only.nil? && !except.nil?

  @attributes |= instance_vars_with_readers if @include_readable_instance_variables

  @attributes = only unless only.nil?
  @attributes = attributes - except unless except.nil?
  attributes
end
reference_to(key) click to toggle source
# File lib/simply_serializable/serializer.rb, line 186
def reference_to(key)
  {
    object: :reference,
    id: key
  }
end
serialize_object(use_object) click to toggle source
# File lib/simply_serializable/serializer.rb, line 163
def serialize_object(use_object)
  use_object_cache_key = cache_key_for(use_object)
  if @local_cache.key?(use_object_cache_key)
    @nestable = false
    return reference_to(use_object_cache_key)
  end

  serializer =  if !use_object.respond_to?(:serialize)
                  raise "#{use_object.class.name} does not respond to serialize.  Did you mean to include Serializable in this class?" unless @include_readable_instance_variables

                  Serializer.new(
                    cache: @local_cache,
                    do_not_serialize_if_class_is: do_not_serialize_if_class_is,
                    object: use_object
                  )
                else
                  use_object.simply_serializer(cache: @local_cache)
                end

  @local_cache.merge!(serializer.cache)
  reference_to(use_object_cache_key)
end