defmodule Strom.Source.ReadLines do @moduledoc "Source for reading a file line by line" @behaviour Strom.Source defstruct path: nil, file: nil def new(path) when is_binary(path), do: %__MODULE__{path: path} @impl true def start(%__MODULE__{} = read_lines), do: %{read_lines | file: File.open!(read_lines.path)} @impl true def call(%__MODULE__{} = read_lines) do case read_line(read_lines.file) do {:ok, data} -> {[String.trim(data)], read_lines} {:error, :eof} -> {:halt, read_lines} end end @impl true def stop(%__MODULE__{} = read_lines), do: %{read_lines | file: File.close(read_lines.file)} defp read_line(file) do case IO.read(file, :line) do data when is_binary(data) -> {:ok, data} :eof -> {:error, :eof} {:error, :terminated} -> {:error, :eof} {:error, reason} -> raise reason end end end