Sha256: 59a2f55f3e8beef25919a4513d1a17e720b8043233539b78d6131e3c42e9015d

Contents?: true

Size: 1.56 KB

Versions: 5

Compression:

Stored size: 1.56 KB

Contents

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

module ROM
  # @api private
  class MapperCompiler
    extend Initializer

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

    attr_reader :struct_compiler

    def initialize(*args)
      super
      @struct_compiler = StructCompiler.new(cache: cache)
      @cache = cache.namespaced(:mappers)
    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 = node
      name = meta[:combine_name] || meta[:alias] || rel_name
      namespace = meta.fetch(:struct_namespace)

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

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

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

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

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

      if meta[:wrapped]
        [name, from: meta[:alias]]
      else
        [name]
      end
    end
  end
end

Version data entries

5 entries across 5 versions & 1 rubygems

Version Path
rom-mapper-1.0.2 lib/rom/mapper_compiler.rb
rom-mapper-1.0.1 lib/rom/mapper_compiler.rb
rom-mapper-1.0.0 lib/rom/mapper_compiler.rb
rom-mapper-1.0.0.rc2 lib/rom/mapper_compiler.rb
rom-mapper-1.0.0.rc1 lib/rom/mapper_compiler.rb