Sha256: 34413f5e7e98af846cba524a1fdedeed3a1b131dfca6238a5db224e4291d64dc

Contents?: true

Size: 1.35 KB

Versions: 3

Compression:

Stored size: 1.35 KB

Contents

# typed: strict
# frozen_string_literal: true

# Creates initialization payload for targeted T::Struct
class PropsBuilder
  extend T::Sig

  sig do
    params(
      model: ActiveRecord::Base,
      target_struct: T.class_of(T::Struct)
    ).void
  end
  def initialize(model:, target_struct:)
    @model = model
    @target_struct = target_struct
  end

  sig { returns(T::Hash[Symbol, T.untyped]) }
  def build
    target_struct.props.keys.each_with_object({}) do |prop_name, returned_props|
      attribute = model.respond_to?(prop_name) ? build_attribute(prop_name) : nil

      returned_props[prop_name] = attribute
    end
  end

  private

  sig { params(prop_name: Symbol).returns(T.untyped) }
  def build_attribute(prop_name)
    attribute = model.send(prop_name)
    prop_type = target_struct.props.dig(prop_name, :type)

    cast_attribute(attribute, prop_type)
  end

  sig { params(attribute: T.untyped, prop_type: Class).returns(T.untyped) }
  def cast_attribute(attribute, prop_type)
    if prop_type < T::Enum
      prop_type.deserialize(attribute)
    elsif prop_type < T::Struct
      prop_type.new(PropsBuilder.new(model: attribute, target_struct: prop_type).build)
    else
      attribute
    end
  rescue KeyError
    nil
  end

  sig { returns(ActiveRecord::Base) }
  attr_reader :model

  sig { returns(T.class_of(T::Struct)) }
  attr_reader :target_struct
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
activerecord-ejection_seat-0.3.2 lib/activerecord-ejection_seat/props_builder.rb
activerecord-ejection_seat-0.3.1 lib/activerecord-ejection_seat/props_builder.rb
activerecord-ejection_seat-0.3.0 lib/activerecord-ejection_seat/props_builder.rb