Skip to content

Instantly share code, notes, and snippets.

@rhbvkleef
Created December 31, 2018 21:56
Show Gist options
  • Save rhbvkleef/1b3930122a49b6f9206d5f874db8bbf8 to your computer and use it in GitHub Desktop.
Save rhbvkleef/1b3930122a49b6f9206d5f874db8bbf8 to your computer and use it in GitHub Desktop.
defmodule Comeonin.Crypt do
use Agent
@callback check_pass(map(), String.t()) :: {:ok, map()} | {:error, String.t()}
@callback hashpwsalt(String.t(), Keyword.t()) :: String.t()
@callback checkpw(String.t(), String.t()) :: boolean()
@callback dummy_checkpw(Keyword.t()) :: false
@callback add_hash(String.t(), Keyword.t()) :: map()
@callback can_verify_hash(String.t()) :: boolean()
@callback needs_rehash(String.t(), Keyword.t()) :: boolean()
@spec flatten([[arg]]) :: [arg] when arg: var
defp flatten([]), do: []
defp flatten([h|t]), do: h ++ flatten(t)
defp flatten(h), do: h
defmacro __using__(_opts) do
module = Module.concat([__MODULE__, Auto, __CALLER__.module])
quote do
@behaviour unquote(__MODULE__)
defmodule unquote(module) do
def module, do: (unquote(__CALLER__.module))
end
end
end
@spec find_implementors() :: list(module())
def find_implementors do
pid = Process.whereis(__MODULE__)
if pid do
Agent.get(pid, &(&1))
else
{:ok, p} = Agent.start_link(&_find_implementors/0, name: __MODULE__)
Agent.get(p, &(&1))
end
end
@spec _find_implementors() :: list(module())
defp _find_implementors do
auto_prefix = to_string(Module.concat([__MODULE__, Auto]))
:application.loaded_applications()
|> Enum.map(&(elem(&1, 0) |> Application.spec(:modules)))
|> flatten
|> Enum.filter(&(to_string(&1) |> String.starts_with?(auto_prefix)))
|> Enum.map(&(&1.module))
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment