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
t()
View Source
t() :: term()
t() :: term()
Link to this section Functions
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 argumentoverride
- the value with whichoriginal
would be overridden in a normalMap.merge/2
resolver
- the function used by DeepMerge to resolve merge conflicts, i.e. what you can pass toMap.merge/3
andKeyword.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