Packages

Lazy, external iterators for Elixir.

Current section

Files

Jump to
iterex lib iter iterable concatenator.ex
Raw

lib/iter/iterable/concatenator.ex

defmodule Iter.Iterable.Concatenator do
defstruct current_iterable: nil, outer_iterable: nil
@moduledoc """
An iterable which can concatenate a number of iterables.
"""
alias Iter.{Impl, IntoIterable, Iterable}
@type t :: %__MODULE__{outer_iterable: Iterable.t(), current_iterable: Iterable.t()}
@doc """
Create a new concatenator out of an iterable of iterables.
"""
@spec new(Iterable.t()) :: Iterable.t()
def new(iterable), do: %__MODULE__{outer_iterable: iterable}
defimpl Iterable do
use Impl
@doc false
@impl true
def next(concat) when is_nil(concat.current_iterable) do
case Iterable.next(concat.outer_iterable) do
{:ok, element, iterable} ->
next(%{concat | current_iterable: element, outer_iterable: iterable})
:done ->
:done
end
end
def next(concat) do
case Iterable.next(concat.current_iterable) do
{:ok, element, iterable} -> {:ok, element, %{concat | current_iterable: iterable}}
:done -> next(%{concat | current_iterable: nil})
end
end
end
defimpl IntoIterable do
@doc false
def into_iterable(self), do: self
end
end