class Attr::Gather::Aggregators::DeepMerge

Deep merges result hashes

@api public

Constants

ARRAY_STRATEGY

Public Class Methods

new(reverse: false, merge_input: true, array_strategy: :concat, **) click to toggle source

Initialize a new DeepMerge aggregator

@param reverse [Boolean] deep merge results in reverse order @param merge_input [Boolean] merge the result with the initial input @param array_strategy [Symbol] strategy for handling arrays, one of (:concat, :overwrite)

@api private

Calls superclass method Attr::Gather::Aggregators::Base::new
# File lib/attr/gather/aggregators/deep_merge.rb, line 19
def initialize(reverse: false, merge_input: true, array_strategy: :concat, **)
  unless ARRAY_STRATEGY.include?(array_strategy)
    raise ArgumentError, 'array_strategy must be one of: :concat, :overwrite'
  end

  @reverse = reverse
  @merge_input = merge_input
  @array_strategy = array_strategy

  super
end

Public Instance Methods

call(input, execution_results) click to toggle source
# File lib/attr/gather/aggregators/deep_merge.rb, line 31
def call(input, execution_results)
  execution_results = execution_results.reverse_each if reverse?

  execution_results.reduce(@merge_input ? input : EMPTY_HASH) do |memo, res|
    deep_merge(memo, unwrap_result(res))
  end
end

Private Instance Methods

concattable?(orig, new) click to toggle source
# File lib/attr/gather/aggregators/deep_merge.rb, line 57
def concattable?(orig, new)
  return false unless @array_strategy == :concat

  concattable_class?(orig) && concattable_class?(new)
end
concattable_class?(obj) click to toggle source
# File lib/attr/gather/aggregators/deep_merge.rb, line 63
def concattable_class?(obj)
  return true if obj.is_a?(Array)
  return true if obj.is_a?(Set)

  false
end
deep_merge(hash, other) click to toggle source
# File lib/attr/gather/aggregators/deep_merge.rb, line 45
def deep_merge(hash, other)
  hash.to_h.merge(other) do |_, orig, new|
    if orig.respond_to?(:to_hash) && new.respond_to?(:to_hash)
      deep_merge(orig.to_h, new.to_h)
    elsif concattable?(orig, new)
      orig + new
    else
      new
    end
  end
end
reverse?() click to toggle source
# File lib/attr/gather/aggregators/deep_merge.rb, line 70
def reverse?
  @reverse
end