Class: Philiprehberger::TomlKit::Merger

Inherits:
Object
  • Object
show all
Defined in:
lib/philiprehberger/toml_kit/merger.rb

Overview

Deep merge two TOML hashes with configurable conflict resolution.

Strategies:

- :override       -> right-side wins (default)
- :keep_existing  -> left-side wins
- :error_on_conflict -> raise MergeConflictError

Constant Summary collapse

STRATEGIES =
%i[override keep_existing error_on_conflict].freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(strategy = :override) ⇒ Merger

Returns a new instance of Merger.

Parameters:

  • strategy (Symbol) (defaults to: :override)


28
29
30
31
32
33
34
# File 'lib/philiprehberger/toml_kit/merger.rb', line 28

def initialize(strategy = :override)
  unless STRATEGIES.include?(strategy)
    raise ArgumentError, "Unknown merge strategy: #{strategy}. Use one of: #{STRATEGIES.join(', ')}"
  end

  @strategy = strategy
end

Class Method Details

.merge(left, right, strategy: :override) ⇒ Hash

Merge two hashes.

Parameters:

  • left (Hash)

    base hash

  • right (Hash)

    hash to merge in

  • strategy (Symbol) (defaults to: :override)

    conflict resolution strategy

Returns:

  • (Hash)

    merged result

Raises:



23
24
25
# File 'lib/philiprehberger/toml_kit/merger.rb', line 23

def self.merge(left, right, strategy: :override)
  new(strategy).merge(left, right)
end

Instance Method Details

#merge(left, right, path = []) ⇒ Hash

Parameters:

  • left (Hash)
  • right (Hash)
  • path (Array<String>) (defaults to: [])

    internal tracking for error messages

Returns:

  • (Hash)


40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/philiprehberger/toml_kit/merger.rb', line 40

def merge(left, right, path = [])
  result = left.dup

  right.each do |key, right_value|
    current_path = path + [key]

    if result.key?(key)
      left_value = result[key]

      result[key] = if left_value.is_a?(Hash) && right_value.is_a?(Hash)
                      merge(left_value, right_value, current_path)
                    else
                      resolve_conflict(left_value, right_value, current_path)
                    end
    else
      result[key] = deep_copy(right_value)
    end
  end

  result
end