Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kianmeng misc doc changes #16

Merged
merged 3 commits into from
Dec 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
# The directory Mix will write compiled artifacts to.
/_build
/_build/

# If you run "mix test --cover", coverage assets end up here.
/cover
/cover/

# The directory Mix downloads your dependencies sources to.
/deps
/deps/

# Where 3rd-party dependencies like ExDoc output generated docs.
/doc
# Where third-party dependencies like ExDoc output generated docs.
/doc/

# Ignore .fetch files in case you like to edit your project deps locally.
/.fetch

# If the VM crashes, it generates a dump, let's ignore it too.
erl_crash.dump

# Also ignore archive artifacts (built via "mix archive.build").
*.ez

# Ignore package tarball (built via "mix hex.build").
deep_merge-*.tar

# Temporary files for e.g. tests.
/tmp/
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 1.0.0 (2019-03-26)

* Added the possibility to `@derive [DeepMerge.Resolver]` if you want your custom structs to also easily be deep_mergeable
Expand Down
31 changes: 20 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# DeepMerge [![Hex Version](https://img.shields.io/hexpm/v/deep_merge.svg)](https://hex.pm/packages/deep_merge) [![docs](https://img.shields.io/badge/docs-hexpm-blue.svg)](https://hexdocs.pm/deep_merge/) [![CI](https://github.com/PragTob/deep_merge/actions/workflows/main.yml/badge.svg)](https://github.com/PragTob/deep_merge/actions/workflows/main.yml) [![Coverage Status](https://coveralls.io/repos/github/PragTob/deep_merge/badge.svg?branch=master)](https://coveralls.io/github/PragTob/deep_merge?branch=master) [![Inline docs](http://inch-ci.org/github/PragTob/deep_merge.svg?branch=master)](http://inch-ci.org/github/PragTob/deep_merge)
# DeepMerge [![Hex Version](https://img.shields.io/hexpm/v/deep_merge.svg)](https://hex.pm/packages/deep_merge) [![docs](https://img.shields.io/badge/docs-hexpm-blue.svg)](https://hexdocs.pm/deep_merge/) [![CI](https://github.com/PragTob/deep_merge/actions/workflows/main.yml/badge.svg)](https://github.com/PragTob/deep_merge/actions/workflows/main.yml) [![Coverage Status](https://coveralls.io/repos/github/PragTob/deep_merge/badge.svg?branch=master)](https://coveralls.io/github/PragTob/deep_merge?branch=master) [![Total Download](https://img.shields.io/hexpm/dt/deep_merge.svg)](https://hex.pm/packages/deep_merge) [![License](https://img.shields.io/hexpm/l/deep_merge.svg)](https://github.com/PragTob/deep_merge/blob/main/LICENSE)

Provides functionality for "deep merging" maps and keyword lists in elixir, which is if during merging both values at the same key are maps/keyword lists merge them recursively. This is done via a protocol so can be extended for your own structs/data types if needbe.

Expand All @@ -24,13 +24,15 @@ I wanted this to be a feature of Elixir itself, however the proposal [was reject

## Installation

Add `deep_merge` to your list of dependencies in `mix.exs`:
Add `:deep_merge` to your list of dependencies in `mix.exs`:

```elixir
def deps do
[{:deep_merge, "~> 1.0"}]
end
```
```elixir
def deps do
[
{:deep_merge, "~> 1.0"}
]
end
```

## General Usage - deep_merge/2

Expand All @@ -50,7 +52,7 @@ It is worth noting that structs are not deeply merged - not with each other and

What is merged and how is defined by implementing the `DeepMerge.Resolver` protocol. This library implements it for `Map`, `List` and falls back to `Any` (where the right hand side value/override is taken).

If you want your own struct to be deeply merged you can simply `@derive` the protocole:
If you want your own struct to be deeply merged you can simply `@derive` the protocol:

```elixir
defmodule Derived do
Expand Down Expand Up @@ -98,7 +100,7 @@ iex> DeepMerge.deep_merge(%{a: %{b: 1}, c: [d: 1]},
%{a: %{b: 1, z: 5}, c: [x: 0]}
```

This function is called for a given merge conflict with the key where it occured and the two conflicting values. Whatever value is returned in this function is inserted at that point in the structure - unless `DeepMerge.continue_deep_merge` is returned in which case the deep merge continues as normal.
This function is called for a given merge conflict with the key where it occurred and the two conflicting values. Whatever value is returned in this function is inserted at that point in the structure - unless `DeepMerge.continue_deep_merge` is returned in which case the deep merge continues as normal.

When would you want to use this versus a protocol? The best use case I can think of is when you want to alter behavior for which a protocol is already implemented or if you care about specific keys.

Expand All @@ -111,7 +113,7 @@ Well not necessarily, no. There are [very simple implementations for maps that u
There are subtle things that can be missed there though (and I missed the first time around):

* the most simple implementation also merges structs which is not always what you want
* For keyword lists on the other hand you gotta be careful that you don't accidentally merge keyword lists with lists as that's [currently possible](https://github.com/elixir-lang/elixir/issues/5395)
* for keyword lists on the other hand you gotta be careful that you don't accidentally merge keyword lists with lists as that's [currently possible](https://github.com/elixir-lang/elixir/issues/5395)
* you might want to further adopt the implementation, in [benchee](https://github.com/bencheeorg/benchee) we have 2 custom implementations of the protocol due to our needs

This library takes care of those problems and will take care of further problems/edge cases should they appear so you can focus on your business logic.
Expand All @@ -120,10 +122,17 @@ At the same time it offers extension mechanisms through protocols and a function

## Performance

You can check out [a benchmark and its results](https://github.com/PragTob/deep_merge/blob/master/benches/bench/deep_merge.exs).
You can check out [a benchmark and its results](https://github.com/PragTob/deep_merge/blob/main/benches/bench/deep_merge.exs).

The TLDR; is this: In the sample it is about 30 times slower than `Map.merge/2` - however, less than twice as slow as calling `Map.merge/3` with simple overriding behaviour (same behaviour as `Map.merge/2`). This is because `Map.merge/2` is highly optimized, but we need to do much more than the `Map.merge/3` sample in the benchmark so I think it's a very passable result. We're still talking about a couple of μs.

## Considered feature-complete

Unless you come with great feature ideas of course ;) So if you come here and there are no recent commits, don't worry - there are no known bugs or whatever. It's a small little library that does its job.

## Copyright and License

Copyright (c) 2016 Tobias Pfeiffer

This library is MIT licensed. See the
[LICENSE](https://github.com/PragTob/deep_merge/blob/main/LICENSE.txt) for details.
46 changes: 26 additions & 20 deletions mix.exs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
defmodule DeepMerge.Mixfile do
use Mix.Project

@source_url "https://github.com/PragTob/deep_merge"
@version "1.0.0"

def project do
Expand All @@ -12,58 +13,63 @@ defmodule DeepMerge.Mixfile do
start_permanent: Mix.env() == :prod,
elixirc_paths: elixirc_paths(Mix.env()),
deps: deps(),
docs: [source_ref: @version],
docs: docs(),
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.
""",
dialyzer: [
flags: [:error_handling, :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.
"""
preferred_cli_env: [
docs: :docs,
coveralls: :test,
"coveralls.detail": :test,
"coveralls.post": :test,
"coveralls.html": :test,
"coveralls.travis": :test
]
]
end

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

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

defp deps do
[
{:credo, "~> 1.0", only: :dev},
{:ex_doc, "~> 0.11", only: :dev},
{:earmark, "~> 1.2", only: :dev},
{:ex_doc, ">= 0.0.0", only: :docs, runtime: false},
{:excoveralls, "~> 0.7", only: :test},
{:inch_ex, "~> 2.0", only: :docs},
{:dialyxir, "~> 1.0", only: [:dev], runtime: false}
]
end

defp docs do
[
extras: ["CHANGELOG.md", "README.md"],
main: "readme",
source_url: @source_url,
source_ref: @version
]
end

defp package do
[
maintainers: ["Tobias Pfeiffer"],
licenses: ["MIT"],
links: %{
"github" => "https://github.com/PragTob/deep_merge"
"Changelog" => "https://hexdocs.pm/deep_merge/changelog.html",
"GitHub" => @source_url
}
]
end
Expand Down
Loading