Current section

Files

Jump to
pipex lib pipex.ex
Raw

lib/pipex.ex

defmodule Pipex do
@moduledoc """
Use:
defmodule Pipeline do
use Pipex
alias __MODULE__
defstruct var1: nil,
var2: []
pipe :local_function
pipe ExternalModule
def run(args) do
token = struct(Pipeline, args)
Pipeline.call(token)
end
def local_function(%Pipeline{} = token) do
# do something with the token and return it
%{token | va1: "var1"}
end
end
def ExternalModule do
def call(%Pipeline{} = token) do
# do something with the token and return it
%{token | var2: [1, 2, 3]}
end
end
"""
defmacro __using__(_opts) do
quote do
Module.register_attribute(__MODULE__, :pipes, accumulate: true)
@before_compile Pipex
import Pipex, only: [pipe: 1]
def call(token) do
do_call(token)
end
end
end
defmacro pipe(module) do
quote do
@pipes unquote(module)
end
end
defmacro __before_compile__(_env) do
quote do
defp do_call(token) do
pipes = Enum.reverse(@pipes)
Pipex.call_pipes(__MODULE__, token, pipes)
end
end
end
def call_pipes(module, initial_token, pipes) do
Enum.reduce(pipes, initial_token, fn pipe, token ->
case Atom.to_charlist(pipe) do
'Elixir.' ++ _ -> pipe.call(token)
_ -> Kernel.apply(module, pipe, [token])
end
end)
end
end