defmodule Matcher.Utils.Lists do import Matcher.Errors alias Matcher.Context def is_enumerable(value) do Enumerable.impl_for(value) != nil end def permutations([]), do: [[]] def permutations(list), do: for(elem <- list, rest <- permutations(list -- [elem]), do: [elem | rest]) def compare_lists(expected, actual, context) do if length(expected) != length(actual) do error(context, type: :list_length_differ, message: "expected length #{expected(length(expected))} but got #{mismatched(length(actual))}" ) else Enum.zip(expected, actual) |> Enum.reduce_while(0, fn {e, a}, index -> case Matcher.match(e, a, Context.append_path(context, index)) do {:ok, _} -> {:cont, index + 1} error -> {:halt, error} end end) |> case do {:error, error} -> {:error, error} _i -> {:ok, nil} end end end end