Sha256: 14016e115059422c574421d67a356cc5e4aa21d99fc430d987dda6b7737a69c9

Contents?: true

Size: 1.94 KB

Versions: 6

Compression:

Stored size: 1.94 KB

Contents

# frozen_string_literal: true

require 'dry/core/class_attributes'

require 'rom/constants'
require 'rom/initializer'
require 'rom/mapper'
require 'rom/struct'
require 'rom/struct_compiler'
require 'rom/cache'

module ROM
  # @api private
  class MapperCompiler
    extend Dry::Core::ClassAttributes
    extend Initializer

    defines :mapper_options

    mapper_options(EMPTY_HASH)

    option :cache, default: -> { Cache.new }

    attr_reader :struct_compiler

    attr_reader :mapper_options

    def initialize(*args)
      super
      @struct_compiler = StructCompiler.new(cache: cache)
      @cache = cache.namespaced(:mappers)
      @mapper_options = self.class.mapper_options
    end

    def call(ast)
      cache.fetch_or_store(ast.hash) { Mapper.build(Header.coerce(*visit(ast))) }
    end
    alias_method :[], :call

    private

    def visit(node)
      name, node = node
      __send__("visit_#{name}", node)
    end

    def visit_relation(node)
      rel_name, header, meta_options = node
      name = meta_options[:combine_name] || meta_options[:alias] || rel_name
      namespace = meta_options.fetch(:struct_namespace)

      model = meta_options.fetch(:model) do
        if meta_options[:combine_name]
          false
        else
          struct_compiler[name, header, namespace]
        end
      end

      options = [header.map(&method(:visit)), mapper_options.merge(model: model)]

      if meta_options[:combine_type]
        type = meta_options[:combine_type] == :many ? :array : :hash
        keys = meta_options.fetch(:keys)

        [name, combine: true, type: type, keys: keys, header: Header.coerce(*options)]
      elsif meta_options[:wrap]
        [name, wrap: true, type: :hash, header: Header.coerce(*options)]
      else
        options
      end
    end

    def visit_attribute(node)
      name, _, meta_options = node

      if meta_options[:alias]
        [meta_options[:alias], from: name]
      else
        [name]
      end
    end
  end
end

Version data entries

6 entries across 6 versions & 1 rubygems

Version Path
rom-core-5.1.2 lib/rom/mapper_compiler.rb
rom-core-5.1.1 lib/rom/mapper_compiler.rb
rom-core-5.1.0 lib/rom/mapper_compiler.rb
rom-core-5.0.2 lib/rom/mapper_compiler.rb
rom-core-5.0.1 lib/rom/mapper_compiler.rb
rom-core-5.0.0 lib/rom/mapper_compiler.rb