Sha256: 0c202db4e198b5061b2aab1ce183cac676a925dd545acd217b8d9af858fa2c63

Contents?: true

Size: 1.84 KB

Versions: 9

Compression:

Stored size: 1.84 KB

Contents

require 'dry/core/class_attributes'

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

      defines :attributes_inferrer, :attr_class

      MissingAttributesError = Class.new(StandardError) do
        def initialize(name, attributes)
          super(
            "Following attributes in #{Relation::Name[name].relation.inspect} schema cannot "\
            "be inferred and have to be defined explicitly: #{attributes.map(&:inspect).join(', ')}"
          )
        end
      end

      DEFAULT_ATTRIBUTES = [EMPTY_ARRAY, EMPTY_ARRAY].freeze

      attributes_inferrer -> * { DEFAULT_ATTRIBUTES }

      attr_class Attribute

      include Dry::Equalizer(:options)

      option :attr_class, default: -> { self.class.attr_class }

      option :enabled, default: -> { true }

      alias_method :enabled?, :enabled

      option :attributes_inferrer, default: -> { self.class.attributes_inferrer }

      # @api private
      def call(schema, gateway)
        if enabled?
          inferred, missing = attributes_inferrer.(schema, gateway, options)
        else
          inferred, missing = DEFAULT_ATTRIBUTES
        end

        attributes = merge_attributes(schema.attributes, inferred)

        check_all_attributes_defined(schema, attributes, missing)

        { attributes: attributes }
      end

      # @api private
      def check_all_attributes_defined(schema, all_known, not_inferred)
        not_defined = not_inferred - all_known.map(&:name)

        if not_defined.size > 0
          raise MissingAttributesError.new(schema.name, not_defined)
        end
      end

      # @api private
      def merge_attributes(defined, inferred)
        defined_names = defined.map(&:name)

        defined + inferred.reject { |attr| defined_names.include?(attr.name) }
      end
    end
  end
end

Version data entries

9 entries across 9 versions & 1 rubygems

Version Path
rom-core-4.1.2 lib/rom/schema/inferrer.rb
rom-core-4.1.1 lib/rom/schema/inferrer.rb
rom-core-4.1.0 lib/rom/schema/inferrer.rb
rom-core-4.0.2 lib/rom/schema/inferrer.rb
rom-core-4.0.1 lib/rom/schema/inferrer.rb
rom-core-4.0.0 lib/rom/schema/inferrer.rb
rom-core-4.0.0.rc2 lib/rom/schema/inferrer.rb
rom-core-4.0.0.rc1 lib/rom/schema/inferrer.rb
rom-core-4.0.0.beta3 lib/rom/schema/inferrer.rb