Packages

A collection of extra utilities and extensions to the Elixir standard library

Current section

Files

Jump to
extra lib behaviour extra.ex
Raw

lib/behaviour/extra.ex

defmodule Behaviour.Extra do
@moduledoc """
Module for useful functions and assertions for Behaviours.
"""
@type behaviour :: module
@doc """
Asserts that the passed behaviour's callbacks are all implemented
by the passed module.
Throws an `ArgumentError` if any are not implemented.
"""
@spec assert_impl!(behaviour, module) :: :ok | no_return
def assert_impl!(behaviour, module) do
callbacks =
callbacks(behaviour)
missing_functions =
callbacks
|> Enum.reject(fn {func, arity} -> function_exported?(module, func, arity) end)
case missing_functions do
[] -> :ok
missing when is_list(missing) ->
formatted =
missing
|> Enum.map(fn {func, arity} -> "#{func}/#{arity}" end)
raise ArgumentError, "module #{module} does not fully implement behaviour #{behaviour}. Missing: #{formatted}"
end
end
@spec callbacks(behaviour) :: [{func :: atom, arity :: non_neg_integer}]
defp callbacks(behaviour) do
behaviour.behaviour_info(:callbacks)
end
end