lib/matcher.ex

defmodule Matcher do
  alias Matcher.Context

  def matches?(expected, actual) do
    case match(expected, actual) do
      {:ok, _} -> true
      _ -> false
    end
  end

  def match(expected, actual, context \\ %Context{}) do
    Matcher.Protocol.match(expected, actual, context)
  end

  def equals(expected) do
    cond do
      is_map(expected) -> %Matcher.MapEquals{expected: expected}
      is_list(expected) -> %Matcher.ListEquals{expected: expected}
      :else -> %Matcher.Value{expected: expected}
    end
  end

  def embeds(expected) when is_map(expected) do
    %Matcher.MapEmbeds{expected: expected}
  end

  def in_any_order(expected) when is_list(expected) do
    %Matcher.ListInAnyOrder{expected: expected}
  end

  def one_of(expecteds) when is_list(expecteds) do
    %Matcher.OneOf{expecteds: expecteds}
  end

  def predicate(predicate) do
    %Matcher.Predicate{predicate: predicate}
  end
end