Sha256: 742808f2d3798f4d5e4df873bd00a6c0cd011913ba4bc6e29fb6d4cf18c23a59

Contents?: true

Size: 1.65 KB

Versions: 54

Compression:

Stored size: 1.65 KB

Contents

# frozen_string_literal: true

class ReeObject::ToHash
  include Ree::FnDSL

  fn :to_hash

  RecursiveObjectErr = Class.new(ArgumentError)

  BASIC_TYPES = [
    Date, Time, Numeric, String, FalseClass, TrueClass, NilClass, Symbol,
    Module, Class
  ].freeze

  contract(
    Any => Or[Hash, ArrayOf[Any], *BASIC_TYPES]
  ).throws(RecursiveObjectErr)
  def call(obj)
    recursively_convert(obj, {}, {})
  end

  private

  def recursively_convert(obj, acc, cache)
    ancestors = obj.class.ancestors

    if ancestors.intersection(BASIC_TYPES).size > 0
      obj
    elsif obj.is_a?(Array)
      convert_array(obj, acc, cache)
    elsif obj.is_a?(Hash)
      convert_hash(obj, acc, cache)
    elsif obj.respond_to?(:to_h)
      convert_hash(obj.to_h, acc, cache)
    else
      convert_object(obj, acc, cache)
    end
  end

  def convert_array(obj, acc, cache)
    obj.map { |el| recursively_convert(el, {}, cache) }
  end

  def convert_hash(obj, acc, cache)
    obj.each do |k, v|
      key_sym = k.to_sym
      acc[key_sym] = recursively_convert(v, {}, cache)
    end

    acc
  end

  def convert_object(obj, acc, cache)
    return obj if obj.is_a?(Class) || obj.is_a?(Module)

    if cache.key?(obj.object_id)
      raise RecursiveObjectErr, "Recursive object found: #{obj}"
    end

    cache[obj.object_id] = true

    obj.instance_variables.each do |var|
      key_name = var.to_s.delete("@")
      key_sym = key_name.to_sym

      key = key_sym
      value = obj.instance_variable_get(var)

      acc[key] = recursively_convert(value, {}, cache)
    end

    cache.delete(obj.object_id)

    acc
  end
end

Version data entries

54 entries across 54 versions & 1 rubygems

Version Path
ree_lib-1.1.1 lib/ree_lib/packages/ree_object/package/ree_object/functions/to_hash.rb
ree_lib-1.1.0 lib/ree_lib/packages/ree_object/package/ree_object/functions/to_hash.rb
ree_lib-1.0.124 lib/ree_lib/packages/ree_object/package/ree_object/functions/to_hash.rb
ree_lib-1.0.123 lib/ree_lib/packages/ree_object/package/ree_object/functions/to_hash.rb
ree_lib-1.0.122 lib/ree_lib/packages/ree_object/package/ree_object/functions/to_hash.rb
ree_lib-1.0.121 lib/ree_lib/packages/ree_object/package/ree_object/functions/to_hash.rb
ree_lib-1.0.120 lib/ree_lib/packages/ree_object/package/ree_object/functions/to_hash.rb
ree_lib-1.0.119 lib/ree_lib/packages/ree_object/package/ree_object/functions/to_hash.rb
ree_lib-1.0.118 lib/ree_lib/packages/ree_object/package/ree_object/functions/to_hash.rb
ree_lib-1.0.117 lib/ree_lib/packages/ree_object/package/ree_object/functions/to_hash.rb
ree_lib-1.0.116 lib/ree_lib/packages/ree_object/package/ree_object/functions/to_hash.rb
ree_lib-1.0.115 lib/ree_lib/packages/ree_object/package/ree_object/functions/to_hash.rb
ree_lib-1.0.114 lib/ree_lib/packages/ree_object/package/ree_object/functions/to_hash.rb
ree_lib-1.0.113 lib/ree_lib/packages/ree_object/package/ree_object/functions/to_hash.rb
ree_lib-1.0.112 lib/ree_lib/packages/ree_object/package/ree_object/functions/to_hash.rb
ree_lib-1.0.111 lib/ree_lib/packages/ree_object/package/ree_object/functions/to_hash.rb
ree_lib-1.0.110 lib/ree_lib/packages/ree_object/package/ree_object/functions/to_hash.rb
ree_lib-1.0.109 lib/ree_lib/packages/ree_object/package/ree_object/functions/to_hash.rb
ree_lib-1.0.108 lib/ree_lib/packages/ree_object/package/ree_object/functions/to_hash.rb
ree_lib-1.0.107 lib/ree_lib/packages/ree_object/package/ree_object/functions/to_hash.rb