defmodule Moar.Protocol do # @related [test](/test/protocol_test.exs) @moduledoc "Protocol-related functions." @doc """ Returns `x` or raises if `x` does not implment `protocol`. ```elixir iex> Moar.Protocol.implements!(~D[2000-01-02], String.Chars) ~D[2000-01-02] ``` """ @spec implements!(any(), module()) :: any() def implements!(x, protocol) do if implements?(x, protocol), do: x, else: raise("Expected #{inspect(x)} to implement protocol #{inspect(protocol)}") end @doc """ Returns true if `x` implements `protocol`. ```elixir iex> Moar.Protocol.implements?(~D[2000-01-02], String.Chars) true ``` """ @spec implements?(any(), module()) :: boolean() def implements?(x, protocol), do: protocol.impl_for(x) != nil end