Skip to content

Commit

Permalink
fixup! Elixir library: add slice to Enumerable protocol
Browse files Browse the repository at this point in the history
  • Loading branch information
bettio committed Aug 14, 2024
1 parent 4d60585 commit af6b3fe
Showing 1 changed file with 15 additions and 17 deletions.
32 changes: 15 additions & 17 deletions libs/exavmlib/lib/Enum.ex
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,12 @@ defmodule Enum do
defp entry_to_string(entry) when is_binary(entry), do: entry
defp entry_to_string(entry), do: String.Chars.to_string(entry)

## drop

defp drop_list(list, 0), do: list
defp drop_list([_ | tail], counter), do: drop_list(tail, counter - 1)
defp drop_list([], _), do: []

## slice

defp slice_any(enumerable, start, amount) when start < 0 do
Expand All @@ -636,11 +642,11 @@ defmodule Enum do
end

defp slice_any(list, start, amount) when is_list(list) do
Enumerable.List.slice(list, start, amount)
list |> drop_list(start) |> take_list(amount)
end

defp slice_any(enumerable, start, amount) do
case backwards_compatible_slice(enumerable) do
case Enumerable.slice(enumerable) do
{:ok, count, _} when start >= count ->
[]

Expand Down Expand Up @@ -669,11 +675,12 @@ defmodule Enum do
end

defp slice_count_and_fun(enumerable) when is_list(enumerable) do
{length(enumerable), &Enumerable.List.slice(enumerable, &1, &2)}
length = length(enumerable)
{length, &Enumerable.List.slice(enumerable, &1, &2, length)}
end

defp slice_count_and_fun(enumerable) do
case backwards_compatible_slice(enumerable) do
case Enumerable.slice(enumerable) do
{:ok, count, fun} when is_function(fun) ->
{count, fun}

Expand All @@ -683,20 +690,11 @@ defmodule Enum do
{:cont, {[elem | acc], count + 1}}
end)

{count, &Enumerable.List.slice(:lists.reverse(list), &1, &2)}
{count, &Enumerable.List.slice(:lists.reverse(list), &1, &2, count)}
end
end

# TODO: Remove me on Elixir v1.9
defp backwards_compatible_slice(args) do
try do
Enumerable.slice(args)
catch
:error, :undef ->
case __STACKTRACE__ do
[{module, :slice, [^args], _} | _] -> {:error, module}
stack -> :erlang.raise(:error, :undef, stack)
end
end
end
defp take_list([head | _], 1), do: [head]
defp take_list([head | tail], counter), do: [head | take_list(tail, counter - 1)]
defp take_list([], _counter), do: []
end

0 comments on commit af6b3fe

Please sign in to comment.