deep_merge v1.0.0 DeepMerge.Resolver protocol View Source

Protocol defining how conflicts during deep_merge should be resolved.

As part of the DeepMerge library this protocol is already implemented for Map and List as well as a fallback to Any (which just always takes the override).

If you want your custom structs to also be deeply mergable and not just override one another (default behaviour) you can derive the protocol:

defmodule Derived do
  @derive [DeepMerge.Resolver]
  defstruct [:attrs]
end

It will then automatically be deeply merged with structs of its own kind, not with other structs or maps though.

Link to this section Summary

Functions

Defines what happens when a merge conflict occurs on this struct during a deep_merge

Link to this section Types

Link to this section Functions

Link to this function

resolve(original, override, resolver) View Source

Defines what happens when a merge conflict occurs on this struct during a deep_merge.

Can be implemented for additional data types to implement custom deep merging behavior.

The passed in values are:

  • original - the value in the original data structure, usually left side argument
  • override - the value with which original would be overridden in a normal Map.merge/2
  • resolver - the function used by DeepMerge to resolve merge conflicts, i.e. what you can pass to Map.merge/3 and Keyword.merge/3 to continue deeply merging.

An example implementation might look like this if you want to deeply merge your struct but only against non nil values (because all keys are always there) if you merge against the same struct (but still merge with maps):

defimpl DeepMerge.Resolver, for: MyStruct do
  def resolve(original, override = %MyStruct{}, resolver) do
    cleaned_override =
      override
      |> Map.from_struct()
      |> Enum.reject(fn {_key, value} -> is_nil(value) end)
      |> Map.new()

    Map.merge(original, cleaned_override, resolver)
  end

  def resolve(original, override, resolver) when is_map(override) do
    Map.merge(original, override, resolver)
  end
end