Skip to content

Commit

Permalink
[#5] – Refactor some modules to better project organization
Browse files Browse the repository at this point in the history
  • Loading branch information
cabol committed Feb 13, 2017
1 parent bd472b7 commit 9a4680f
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 79 deletions.
14 changes: 7 additions & 7 deletions lib/ex_shards.ex
Original file line number Diff line number Diff line change
Expand Up @@ -47,22 +47,22 @@ defmodule ExShards do
* [API Reference](http://cabol.github.io/shards)
"""

use ExShards.API

@type tab :: atom
@type key :: term
@type value :: term
@type state :: ExShards.State.t
use ExShards.Construct

## API

construct :shards, exclude_all: [:start, :stop], exclude: [new: 2]
inject :shards, except: [:start, :stop, new: 2]

@doc false
def new(tab, opts \\ []), do: :shards.new(tab, opts)

## Extended API

@type tab :: atom
@type key :: term
@type value :: term
@type state :: ExShards.State.t

@spec drop(tab, Enumerable.t) :: map
def drop(tab, keys), do: call(tab, :drop, [tab, keys])

Expand Down
52 changes: 0 additions & 52 deletions lib/ex_shards/api.ex

This file was deleted.

84 changes: 84 additions & 0 deletions lib/ex_shards/construct.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
defmodule ExShards.Construct do
@moduledoc """
This is an utility module, which provides a set of macros to
inject functions from Erlang modules.
"""

@doc false
defmacro __using__(_opts) do
quote do
@before_compile unquote(__MODULE__)

import unquote(__MODULE__)
end
end

@doc false
defmacro __before_compile__(_env) do
quote do
@public_defs Module.definitions_in(__MODULE__, :def)

def definitions, do: @public_defs
end
end

@doc """
Injects exported functions from an Erlang module.
By default, it injects all functions from the given module:
inject :lists
Alternatively, it allows you to pass pairs of name/arities to `:except`
as a fine grained control on what to inject (or not):
inject :lists, except: [append: 1]
Besides, it allows you to pass only the name of the fuction(s) to `:except`,
in order to exclude all function that matches with that name – no matter
the arity. E.g.:
inject :lists, except: [:append]
This will exclude either `:lists.append/1` and `:lists.append/2`.
## Example
defmodule Utils do
use ExShards.Construct
# injects all exported functions in module `:lists`
inject :lists
# injects all exported functions in module `:maps` except:
# `:maps.get/2`, `:maps.get/3` and `:maps.find/2`.
inject :maps, except: [:get, find: 2]
end
"""
defmacro inject(mod, opts \\ []) do
# build public function list
public_defs = opts
|> Keyword.get(:except, [])
|> :lists.append([:module_info])
|> Enum.reduce(mod.module_info(:exports), fn
({k, v}, acc) -> Keyword.delete(acc, k, v)
(k, acc) -> Keyword.delete(acc, k)
end)

# generate definitions
for {fun, arity} <- public_defs do
args = if arity > 0 do
1..arity
|> Enum.map(&(Module.concat(["arg#{&1}"])))
|> Enum.map(fn(x) -> {x, [], __MODULE__} end)
else
[]
end
quote do
def unquote(fun)(unquote_splicing(args)) do
unquote(mod).unquote(fun)(unquote_splicing(args))
end
end
end
end
end
7 changes: 4 additions & 3 deletions lib/ex_shards/dist.ex
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,11 @@ defmodule ExShards.Dist do
* [API Reference](http://cabol.github.io/shards)
"""

use ExShards.API
#use ExShards.API.Ext
use ExShards.Construct
#use ExShards.Ext

construct :shards_dist, exclude: [new: 2]
inject :shards_dist, except: [new: 2]

@doc false
def new(tab, opts \\ []), do: :shards_dist.new(tab, opts)
end
4 changes: 2 additions & 2 deletions lib/ex_shards/api/ext.ex → lib/ex_shards/ext.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
defmodule ExShards.API.Ext do
defmodule ExShards.Ext do
@moduledoc """
This module extends the Shards API providing some extra functions.
Expand Down Expand Up @@ -43,7 +43,7 @@ defmodule ExShards.API.Ext do
@doc false
defmacro __using__(_opts) do
quote do
@behaviour ExShards.API.Ext
@behaviour ExShards.Ext

def drop(tab, keys, state \\ ExShards.State.new) do
Enum.reduce(keys, %{}, fn(key, acc) ->
Expand Down
7 changes: 4 additions & 3 deletions lib/ex_shards/local.ex
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@ defmodule ExShards.Local do
* [API Reference](http://cabol.github.io/shards)
"""

use ExShards.API
use ExShards.API.Ext
use ExShards.Construct
use ExShards.Ext

construct :shards_local, exclude: [new: 2]
inject :shards_local, except: [new: 2]

@doc false
def new(tab, opts \\ []), do: :shards_local.new(tab, opts)
end
17 changes: 9 additions & 8 deletions lib/ex_shards/state.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ defmodule ExShards.State do
Shards State.
This module overrides the original `shards_state` getter and setter
functions in order to make them more pipe-operator friendly.
functions in order to make them more Elixir-friendly – e.g.: take
advantage of pipe-operator.
## Examples
Expand All @@ -18,7 +19,7 @@ defmodule ExShards.State do
* [Shards](https://github.com/cabol/shards/blob/master/src/shards_state.erl)
"""

use ExShards.API
use ExShards.Construct

require Record

Expand All @@ -41,29 +42,29 @@ defmodule ExShards.State do
pick_shard_fun: pick_fun,
pick_node_fun: pick_fun])

construct :shards_state,
exclude: [
inject :shards_state,
except: [
module: 2,
n_shards: 2,
pick_shard_fun: 2,
pick_node_fun: 2]

@doc false
@spec module(t, module) :: t
def module(state, module) do
:shards_state.module(module, state)
end

@doc false
@spec n_shards(t, integer) :: t
def n_shards(state, n_shards) do
:shards_state.n_shards(n_shards, state)
end

@doc false
@spec pick_shard_fun(t, pick_fun) :: t
def pick_shard_fun(state, pick_shard_fun) do
:shards_state.pick_shard_fun(pick_shard_fun, state)
end

@doc false
@spec pick_node_fun(t, pick_fun) :: t
def pick_node_fun(state, pick_node_fun) do
:shards_state.pick_node_fun(pick_node_fun, state)
end
Expand Down
7 changes: 5 additions & 2 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ defmodule ExShards.Mixfile do

def project do
[app: :ex_shards,
version: "0.1.0",
version: "0.2.0",
elixir: "~> 1.2",
build_embedded: Mix.env == :prod,
start_permanent: Mix.env == :prod,
deps: deps(),
test_coverage: [tool: ExCoveralls],
preferred_cli_env: ["coveralls": :test, "coveralls.detail": :test, "coveralls.post": :test, "coveralls.html": :test],
package: package(),
description: "ExShards – Elixir Wrapper for cabol/shards"]
end
Expand All @@ -19,7 +21,8 @@ defmodule ExShards.Mixfile do
defp deps do
[{:shards, "~> 0.4"},
{:ex2ms, "~> 1.4"},
{:ex_doc, ">= 0.0.0", only: :dev}]
{:ex_doc, ">= 0.0.0", only: :dev},
{:excoveralls, "~> 0.6.2", only: :test}]
end

defp package do
Expand Down
13 changes: 11 additions & 2 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
%{"earmark": {:hex, :earmark, "1.1.1", "433136b7f2e99cde88b745b3a0cfc3fbc81fe58b918a09b40fce7f00db4d8187", [:mix], []},
%{"certifi": {:hex, :certifi, "0.7.0", "861a57f3808f7eb0c2d1802afeaae0fa5de813b0df0979153cbafcd853ababaf", [:rebar3], []},
"earmark": {:hex, :earmark, "1.1.1", "433136b7f2e99cde88b745b3a0cfc3fbc81fe58b918a09b40fce7f00db4d8187", [:mix], []},
"ex2ms": {:hex, :ex2ms, "1.4.0", "e43b410888b45ba363ea6650db3736db3e455a0a412ec244ac633fede857bcb2", [:mix], []},
"ex_doc": {:hex, :ex_doc, "0.14.5", "c0433c8117e948404d93ca69411dd575ec6be39b47802e81ca8d91017a0cf83c", [:mix], [{:earmark, "~> 1.0", [hex: :earmark, optional: false]}]},
"shards": {:hex, :shards, "0.4.0", "456f0ed35a30aae2bd7c5b8e565d2008c45f82f0ef06e5927a3d9267b0a20a19", [:make, :rebar3], []}}
"excoveralls": {:hex, :excoveralls, "0.6.2", "0e993d096f1fbb6e70a3daced5c89aac066bda6bce57829622aa2d1e2b338cfb", [:mix], [{:exjsx, "~> 3.0", [hex: :exjsx, optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, optional: false]}]},
"exjsx": {:hex, :exjsx, "3.2.1", "1bc5bf1e4fd249104178f0885030bcd75a4526f4d2a1e976f4b428d347614f0f", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, optional: false]}]},
"hackney": {:hex, :hackney, "1.6.5", "8c025ee397ac94a184b0743c73b33b96465e85f90a02e210e86df6cbafaa5065", [:rebar3], [{:certifi, "0.7.0", [hex: :certifi, optional: false]}, {:idna, "1.2.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, "1.2.0", "ac62ee99da068f43c50dc69acf700e03a62a348360126260e87f2b54eced86b2", [:rebar3], []},
"jsx": {:hex, :jsx, "2.8.2", "7acc7d785b5abe8a6e9adbde926a24e481f29956dd8b4df49e3e4e7bcc92a018", [:mix, :rebar3], []},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], []},
"mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], []},
"shards": {:hex, :shards, "0.4.0", "456f0ed35a30aae2bd7c5b8e565d2008c45f82f0ef06e5927a3d9267b0a20a19", [:make, :rebar3], []},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], []}}

0 comments on commit 9a4680f

Please sign in to comment.