lib/matchers/list.ex

defmodule Matcher.ListEquals do
  defstruct [:expected]

  defimpl Matcher.Protocol do
    def match(%{expected: expected}, actual, context) do
      Matcher.Utils.Lists.compare_lists(expected, actual, context)
    end
  end
end

defmodule Matcher.ListInAnyOrder do
  defstruct [:expected]

  import Matcher.Errors

  defimpl Matcher.Protocol do
    def match(%{expected: expected}, actual, context) do
      matched =
        Matcher.Utils.Lists.permutations(expected)
        |> Enum.find(fn candidate ->
          Matcher.matches?(candidate, actual)
        end)

      if matched do
        {:ok, nil}
      else
        error(context, message: "lorem")
      end
    end
  end
end

defimpl Matcher.Protocol, for: List do
  def match(expected, actual, context) do
    Matcher.match(%Matcher.ListEquals{expected: expected}, actual, context)
  end
end