Current section

Files

Jump to
cliex_map lib cliex_map mapper.ex
Raw

lib/cliex_map/mapper.ex

defmodule CliexMap.Mapper do
use CliexMap.Types
alias CliexMap.{Context, Fn, FunctionList}
@moduledoc ~S"""
Maps each line according to pattern to a new, `\n` terminated string
"""
@spec map(Enumerable.t(), list(FunctionList.t()), Context.t()) :: binaries()
def map(input_stream, function_pipeline, context) do
line_numbers = Stream.iterate(0, &(&1 + 1))
numbered_lines =
Stream.zip(line_numbers, input_stream |> Stream.map(&String.trim_trailing(&1, "\n")))
numbered_lines
|> Stream.map(&transform_line(&1, function_pipeline, context))
|> Enum.filter(&is_binary/1)
end
@spec transform_line(numbered_line_t(), list(FunctionList.t()), Context.t()) :: binary()
def transform_line(line, function_pipelines, context) do
with {_context, outputresult} <-
function_pipelines
|> Enum.reduce_while({context, []}, fn pipeline, {ctxt, output} ->
case transform_chunk(line, pipeline, ctxt) do
{ctxt1, output1} -> {:cont, {ctxt1, [output1 | output]}}
:ignore -> {:halt, :ignore}
_value -> raise "Not yet implemented"
end
end) do
case outputresult do
:ignore -> :ignore
o -> o |> Enum.reverse |> Enum.join
end
end
end
@spec transform_chunk(numbered_line_t(), FunctionList.t(), Context.t()) :: any()
defp transform_chunk(line, function_pipeline, context) do
# IO.inspect(function_pipeline, label: :function_pipeline)
#
function_pipeline.functions
|> Enum.reverse()
|> Enum.reduce_while({context, line}, fn function, {ctxt, input} ->
case Fn.call(function, input, ctxt) do
:halt -> {:halt, :ignore}
{:halt, _} = hv -> hv
{_, _} = cc -> {:cont, cc}
text -> {:cont, {ctxt, text}}
end
end)
end
end
# SPDX-License-Identifier: Apache-2.0