Skip to content

Commit

Permalink
Merge 43a4e1d into 084cfac
Browse files Browse the repository at this point in the history
  • Loading branch information
PragTob committed Mar 24, 2019
2 parents 084cfac + 43a4e1d commit b764275
Show file tree
Hide file tree
Showing 10 changed files with 139 additions and 119 deletions.
4 changes: 4 additions & 0 deletions .dialyzer_ignore.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[
~r/__impl__.*does\ not\ exist\./
]

9 changes: 9 additions & 0 deletions .formatter.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[
inputs: [
"lib/**/*.{ex,exs}",
"test/**/*.{ex,exs}",
"mix/**/*.{ex,exs}",
"./mix.exs",
]
]

4 changes: 2 additions & 2 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
elixir 1.8.0
erlang 21.2.2
elixir 1.8.1-otp-21
erlang 21.2.7
30 changes: 8 additions & 22 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,38 +1,24 @@
language: elixir
elixir:
- 1.3.4
- 1.4.5
- 1.5.3
- 1.6.6
- 1.7.4
- 1.8.0
otp_release:
- 18.3
- 19.3
- 20.3
- 21.2
matrix:
exclude:
- elixir: 1.3.4
otp_release: 20.3
- elixir: 1.3.4
otp_release: 21.2
- elixir: 1.4.5
otp_release: 21.2
- elixir: 1.5.3
otp_release: 21.2
- elixir: 1.6.6
otp_release: 18.3
- elixir: 1.7.4
otp_release: 18.3
- elixir: 1.7.4
otp_release: 19.3
- elixir: 1.8.0
otp_release: 18.3
- elixir: 1.8.0
otp_release: 19.3
before_script: MIX_ENV=test mix compile --warnings-as-errors
script: mix coveralls.travis
before_script:
- MIX_ENV=test mix compile --warnings-as-errors
- travis_wait mix dialyzer --plt
script:
- mix credo --strict
- mix format --check-formatted
- mix dialyzer --halt-exit-status --format simple
- mix coveralls.travis
after_script:
- mix deps.get --only docs
- MIX_ENV=docs mix inch.report
Expand Down
31 changes: 14 additions & 17 deletions lib/deep_merge.ex
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ defmodule DeepMerge do
iex> DeepMerge.deep_merge(%{a: [b: %{c: [d: "foo", e: 2]}]}, %{a: [b: %{c: [d: "bar"]}]})
%{a: [b: %{c: [e: 2, d: "bar"]}]}
"""
@spec deep_merge(map() | keyword(), map | keyword()) :: map() | keyword()
def deep_merge(original, override)
when (is_map(original) or is_list(original)) and
(is_map(override) or is_list(override)) do
when (is_map(original) or is_list(original)) and (is_map(override) or is_list(override)) do
standard_resolve(nil, original, override)
end

Expand Down Expand Up @@ -91,14 +91,14 @@ defmodule DeepMerge do
...> %{a: %{z: 5}, c: [x: 0]}, resolver)
%{a: %{b: 1, z: 5}, c: [x: 0]}
"""
@spec deep_merge(map() | keyword(), map() | keyword(), (any(), any() -> any())) ::
map() | keyword()
def deep_merge(original, override, resolve_function)
when (is_map(original) or is_list(original)) and
(is_map(override) or is_list(override)) do
when (is_map(original) or is_list(original)) and (is_map(override) or is_list(override)) do
resolver = build_resolver(resolve_function)
resolver.(nil, original, override)
end


@doc """
The symbol to return in the function in `deep_merge/3` when deep merging
should continue as normal.
Expand All @@ -108,14 +108,18 @@ defmodule DeepMerge do
iex> DeepMerge.continue_deep_merge
:__deep_merge_continue
"""
@spec continue_deep_merge() :: :__deep_merge_continue
def continue_deep_merge, do: @continue_symbol

@spec build_resolver((any(), any() -> any())) :: (any(), any(), any() -> any())
defp build_resolver(resolve_function) do
my_resolver = fn(key, base, override, fun) ->
my_resolver = fn key, base, override, fun ->
resolved_value = resolve_function.(key, base, override)

case resolved_value do
@continue_symbol ->
continue_deep_merge(base, override, fun)
@continue_symbol ->
continue_deep_merge(base, override, fun)

_anything ->
resolved_value
end
Expand All @@ -125,7 +129,7 @@ defmodule DeepMerge do
end

defp rebuild_resolver(resolve_function) do
fn(key, base, override) ->
fn key, base, override ->
resolve_function.(key, base, override, resolve_function)
end
end
Expand All @@ -136,13 +140,6 @@ defmodule DeepMerge do
end

defp standard_resolve(_key, original, override) do
# Why is this wrapped in an anonymous function and not just passing along
# `&standard_resolve/3` ?
# That'd require standard_resolve/3 to be public afaik and I don't want that
resolve = fn(my_key, my_original, my_override) ->
standard_resolve my_key, my_original, my_override
end
Resolver.resolve(original, override, resolve)
Resolver.resolve(original, override, &standard_resolve/3)
end

end
4 changes: 4 additions & 0 deletions lib/deep_merge/resolver.ex
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,11 @@ defimpl DeepMerge.Resolver, for: Map do
def resolve(_original, override = %{__struct__: _}, _fun) do
override
end

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

def resolve(_original, override, _fun), do: override
end

Expand All @@ -66,9 +68,11 @@ defimpl DeepMerge.Resolver, for: List do
def resolve(original = [{_k, _v} | _], override = [{_, _} | _], resolver) do
Keyword.merge(original, override, resolver)
end

def resolve(original = [{_k, _v} | _tail], _override = [], _fun) do
original
end

def resolve(_original, override, _fun), do: override
end

Expand Down
69 changes: 38 additions & 31 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,49 +4,57 @@ defmodule DeepMerge.Mixfile do
@version "0.2.0"

def project do
[app: :deep_merge,
version: @version,
elixir: "~> 1.2",
build_embedded: Mix.env == :prod,
start_permanent: Mix.env == :prod,
elixirc_paths: elixirc_paths(Mix.env),
deps: deps(),
docs: [source_ref: @version],
test_coverage: [tool: ExCoveralls],
preferred_cli_env: [
coveralls: :test, "coveralls.detail": :test,
"coveralls.post": :test, "coveralls.html": :test,
"coveralls.travis": :test],
package: package(),
name: "deep_merge",
source_url: "https://github.com/PragTob/deep_merge",
description: """
Deep (recursive) merging for maps, keyword lists and whatever else
you may want via implementing a simple protocol.
"""

]
[
app: :deep_merge,
version: @version,
elixir: "~> 1.6",
build_embedded: Mix.env() == :prod,
start_permanent: Mix.env() == :prod,
elixirc_paths: elixirc_paths(Mix.env()),
deps: deps(),
docs: [source_ref: @version],
test_coverage: [tool: ExCoveralls],
preferred_cli_env: [
coveralls: :test,
"coveralls.detail": :test,
"coveralls.post": :test,
"coveralls.html": :test,
"coveralls.travis": :test
],
package: package(),
name: "deep_merge",
source_url: "https://github.com/PragTob/deep_merge",
dialyzer: [
flags: [:unmatched_returns, :error_handling, :race_conditions, :underspecs],
ignore_warnings: ".dialyzer_ignore.exs",
list_unused_filters: true
],
description: """
Deep (recursive) merging for maps, keyword lists and whatever else
you may want via implementing a simple protocol.
"""
]
end

# Specifies which paths to compile per environment.
defp elixirc_paths(:test), do: ["lib", "test/support"]
defp elixirc_paths(_), do: ["lib"]
defp elixirc_paths(_), do: ["lib"]

# Configuration for the OTP application
#
# Type "mix help compile.app" for more information
def application do
[applications: [:logger]]
[]
end

defp deps do
[
{:credo, "~> 0.5", only: :dev},
{:benchee, "~> 0.5", only: :dev},
{:ex_doc, "~> 0.11", only: :dev},
{:earmark, "~> 1.2", only: :dev},
{:credo, "~> 1.0", only: :dev},
{:ex_doc, "~> 0.11", only: :dev},
{:earmark, "~> 1.2", only: :dev},
{:excoveralls, "~> 0.7", only: :test},
{:inch_ex, "~> 0.5", only: :docs}
{:inch_ex, "~> 0.5", only: :docs},
{:dialyxir, "~> 1.0.0-rc.4", only: [:dev], runtime: false}
]
end

Expand All @@ -55,9 +63,8 @@ defmodule DeepMerge.Mixfile do
maintainers: ["Tobias Pfeiffer"],
licenses: ["MIT"],
links: %{
"github" => "https://github.com/PragTob/deep_merge"
"github" => "https://github.com/PragTob/deep_merge"
}
]
end

end
31 changes: 19 additions & 12 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
%{"benchee": {:hex, :benchee, "0.9.0", "433d946b0e4755e186fe564568ead4f593b0d15337fcffa95ed7d5b8a6612670", [:mix], [{:deep_merge, "~> 0.1", [hex: :deep_merge, optional: false]}]},
%{
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], []},
"certifi": {:hex, :certifi, "2.0.0", "a0c0e475107135f76b8c1d5bc7efb33cd3815cb3cf3dea7aefdd174dabead064", [:rebar3], []},
"credo": {:hex, :credo, "0.8.5", "3002d41c8a9452bd69cb1c217a6e17bf6fd9d8549932fe9f99a51646587c2a65", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, optional: false]}]},
"deep_merge": {:hex, :deep_merge, "0.1.1", "c27866a7524a337b6a039eeb8dd4f17d458fd40fbbcb8c54661b71a22fffe846", [:mix], []},
"earmark": {:hex, :earmark, "1.2.3", "206eb2e2ac1a794aa5256f3982de7a76bf4579ff91cb28d0e17ea2c9491e46a4", [:mix], []},
"ex_doc": {:hex, :ex_doc, "0.16.2", "3b3e210ebcd85a7c76b4e73f85c5640c011d2a0b2f06dcdf5acdb2ae904e5084", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, optional: false]}]},
"excoveralls": {:hex, :excoveralls, "0.7.2", "f69ede8c122ccd3b60afc775348a53fc8c39fe4278aee2f538f0d81cc5e7ff3a", [:mix], [{:exjsx, ">= 3.0.0", [hex: :exjsx, optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, optional: false]}]},
"certifi": {:hex, :certifi, "2.5.1", "867ce347f7c7d78563450a18a6a28a8090331e77fa02380b4a21962a65d36ee5", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"},
"credo": {:hex, :credo, "1.0.3", "5278e8953f379b41ebe27c75c96d2e154ebc3f75dfe057c8b68c39133c25bb9f", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"},
"dialyxir": {:hex, :dialyxir, "1.0.0-rc.4", "71b42f5ee1b7628f3e3a6565f4617dfb02d127a0499ab3e72750455e986df001", [:mix], [{:erlex, "~> 0.1", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm"},
"earmark": {:hex, :earmark, "1.3.1", "73812f447f7a42358d3ba79283cfa3075a7580a3a2ed457616d6517ac3738cb9", [:mix], [], "hexpm"},
"erlex": {:hex, :erlex, "0.2.1", "cee02918660807cbba9a7229cae9b42d1c6143b768c781fa6cee1eaf03ad860b", [:mix], [], "hexpm"},
"ex_doc": {:hex, :ex_doc, "0.19.3", "3c7b0f02851f5fc13b040e8e925051452e41248f685e40250d7e40b07b9f8c10", [:mix], [{:earmark, "~> 1.2", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.10", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"},
"excoveralls": {:hex, :excoveralls, "0.10.6", "e2b9718c9d8e3ef90bc22278c3f76c850a9f9116faf4ebe9678063310742edc2", [:mix], [{:hackney, "~> 1.13", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"},
"exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, optional: false]}]},
"hackney": {:hex, :hackney, "1.9.0", "51c506afc0a365868469dcfc79a9d0b94d896ec741cfd5bd338f49a5ec515bfe", [:rebar3], [{:certifi, "2.0.0", [hex: :certifi, optional: false]}, {:idna, "5.1.0", [hex: :idna, optional: false]}, {:metrics, "1.0.1", [hex: :metrics, optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, optional: false]}]},
"idna": {:hex, :idna, "5.1.0", "d72b4effeb324ad5da3cab1767cb16b17939004e789d8c0ad5b70f3cea20c89a", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, optional: false]}]},
"hackney": {:hex, :hackney, "1.15.1", "9f8f471c844b8ce395f7b6d8398139e26ddca9ebc171a8b91342ee15a19963f4", [:rebar3], [{:certifi, "2.5.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.4", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
"idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
"inch_ex": {:hex, :inch_ex, "0.5.6", "418357418a553baa6d04eccd1b44171936817db61f4c0840112b420b8e378e67", [:mix], [{:poison, "~> 1.5 or ~> 2.0 or ~> 3.0", [hex: :poison, optional: false]}]},
"jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
"jsx": {:hex, :jsx, "2.8.2", "7acc7d785b5abe8a6e9adbde926a24e481f29956dd8b4df49e3e4e7bcc92a018", [:mix, :rebar3], []},
"makeup": {:hex, :makeup, "0.8.0", "9cf32aea71c7fe0a4b2e9246c2c4978f9070257e5c9ce6d4a28ec450a839b55f", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"},
"makeup_elixir": {:hex, :makeup_elixir, "0.13.0", "be7a477997dcac2e48a9d695ec730b2d22418292675c75aa2d34ba0909dcdeda", [:mix], [{:makeup, "~> 0.8", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], []},
"mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], []},
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm"},
"nimble_parsec": {:hex, :nimble_parsec, "0.5.0", "90e2eca3d0266e5c53f8fbe0079694740b9c91b6747f2b7e3c5d21966bba8300", [:mix], [], "hexpm"},
"parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], []},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], []},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [:rebar3], []}}
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.4", "f0eafff810d2041e93f915ef59899c923f4568f4585904d010387ed74988e77b", [:make, :mix, :rebar3], [], "hexpm"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm"},
}
Loading

0 comments on commit b764275

Please sign in to comment.