class Dry::Schema::TypesMerger::ValueMerger

@api private

Attributes

new[R]
old[R]
op_class[R]
types_merger[R]

Public Class Methods

new(types_merger, op_class, old, new) click to toggle source

@api private

# File lib/dry/schema/types_merger.rb, line 21
def initialize(types_merger, op_class, old, new)
  @types_merger = types_merger
  @op_class = op_class
  @old = old
  @new = new
end

Public Instance Methods

call() click to toggle source

@api private

# File lib/dry/schema/types_merger.rb, line 29
        def call
          if op_class <= Dry::Logic::Operations::Or
            merge_or
          elsif op_class <= Dry::Logic::Operations::And
            merge_and
          elsif op_class <= Dry::Logic::Operations::Implication
            merge_implication
          else
            raise ArgumentError, <<~MESSAGE
              Can't merge operations, op_class=#{op_class}
            MESSAGE
          end
        end

Private Instance Methods

merge_and()
Alias for: merge_ordered
merge_equivalent_types(unwrapped_old, unwrapped_new) click to toggle source

@api private

# File lib/dry/schema/types_merger.rb, line 95
        def merge_equivalent_types(unwrapped_old, unwrapped_new)
          if unwrapped_old.primitive <= unwrapped_new.primitive
            unwrapped_new
          elsif unwrapped_new.primitive <= unwrapped_old.primitive
            unwrapped_old
          else
            raise ArgumentError, <<~MESSAGE
              Can't merge types, unwrapped_old=#{unwrapped_old.inspect}, unwrapped_new=#{unwrapped_new.inspect}
            MESSAGE
          end
        end
merge_implication()
Alias for: merge_ordered
merge_or() click to toggle source

@api private

# File lib/dry/schema/types_merger.rb, line 46
def merge_or
  old | new
end
merge_ordered() click to toggle source

@api private

# File lib/dry/schema/types_merger.rb, line 51
def merge_ordered
  return old if old == new

  unwrapped_old, old_rule = unwrap_type(old)
  unwrapped_new, new_rule = unwrap_type(new)

  type = merge_unwrapped_types(unwrapped_old, unwrapped_new)

  rule = [old_rule, new_rule].compact.reduce { op_class.new(_1, _2) }

  type = Dry::Types::Constrained.new(type, rule: rule) if rule

  type
end
Also aliased as: merge_and, merge_implication
merge_schemas(unwrapped_old, unwrapped_new) click to toggle source

@api private

# File lib/dry/schema/types_merger.rb, line 84
def merge_schemas(unwrapped_old, unwrapped_new)
  types_merger.type_registry["hash"].schema(
    types_merger.call(
      op_class,
      unwrapped_old.name_key_map,
      unwrapped_new.name_key_map
    )
  )
end
merge_unwrapped_types(unwrapped_old, unwrapped_new) click to toggle source

@api private

# File lib/dry/schema/types_merger.rb, line 70
def merge_unwrapped_types(unwrapped_old, unwrapped_new)
  case [unwrapped_old, unwrapped_new]
  in Dry::Types::Schema, Dry::Types::Schema
    merge_schemas(unwrapped_old, unwrapped_new)
  in [Dry::Types::AnyClass, _] | [Dry::Types::Hash, Dry::Types::Schema]
    unwrapped_new
  in [Dry::Types::Schema, Dry::Types::Hash] | [_, Dry::Types::AnyClass]
    unwrapped_old
  else
    merge_equivalent_types(unwrapped_old, unwrapped_new)
  end
end
unwrap_type(type) click to toggle source

@api private

# File lib/dry/schema/types_merger.rb, line 108
def unwrap_type(type)
  rules = []

  loop do
    rules << type.rule if type.respond_to?(:rule)

    if type.optional?
      type = type.left.primitive?(nil) ? type.right : type.left
    elsif type.is_a?(Dry::Types::Decorator)
      type = type.type
    else
      break
    end
  end

  [type, rules.reduce(:&)]
end