Generate structural diffs between two Elixir values.
A simple example:
left = %{name: "Alice", age: 30}
right = %{name: "Alice", age: 31, city: "NYC"}
Diffident.explain(left, right)
# Returns:
# [
# {:changed, [:age], 30, 31},
# {:added, [:city], "NYC"}
# ]Here's one returning more complex structural changes:
left = %{
user: [
%{id: 1, name: "Alice"},
%{id: 2, name: "Bob"}
],
meta: {:ok, %{count: 2}}
}
right = %{
user: [
%{id: 1, name: "Alice"},
%{id: 2, name: "Robert"},
%{id: 3, name: "Carol"}
],
meta: {:ok, %{count: 3}}
}
Diffident.explain(left, right)
# Returns:
# [
# {:changed, [:user, {Access, :at, [1]}, :name], "Bob", "Robert"},
# {:added, [:user, {Access, :at, [2]}], %{id: 3, name: "Carol"}},
# {:changed, [:meta, {Access, :elem, [1]}, :count], 2, 3}
#. ]Note that the paths returned are serializable; rather than Access function calls, MFAs are returned, but you can convert them using Diffident.to_access_compatible/1:
Diffident.to_access_compatible([:user, {Access, :at, [1]}, :name])
# Returns:
# [:user, Access.at(1), :name]Skip that intermediate step to use the path directly with Diffident.get_in/2:
data = %{a: [1, %{b: 2}]}
path = [:a, {Access, :at, [1]}, :b]
Diffident.get_in(data, path)
# Returns:
# 2They work with Diffident.put_in/3, too:
data = {[%{x: 1}], 99}
path = [{Access, :elem, [0]}, {Access, :at, [0]}, :x]
updated = Diffident.put_in(data, path, 7)
Diffident.get_in(updated, path) == 7
# Returns:
# true
updated == {[%{x: 7}], 99}
# Returns:
# truedef deps do
[
{:diffident, "~> 0.1.0"}
]
endSee LICENSE.