Packages
reactor
0.15.1
1.0.2
1.0.1
1.0.0
0.17.0
0.16.0
0.15.6
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.0
0.10.3
0.10.2
0.10.1
0.10.0
0.9.1
0.9.0
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.0
0.6.0
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.0
An asynchronous, graph-based execution engine
Current section
Files
Jump to
Current section
Files
lib/reactor/dsl/transformer.ex
defmodule Reactor.Dsl.Transformer do
@moduledoc false
alias Reactor.{Dsl, Info, Planner}
alias Spark.{Dsl.Transformer, Error.DslError}
import Reactor.Dsl.Utils
use Transformer
@doc false
@spec transform(Spark.Dsl.t()) :: {:ok, Spark.Dsl.t()} | {:error, DslError.t()}
def transform(dsl_state) do
with {:ok, step_names} <- step_names(dsl_state),
{:ok, dsl_state} <- maybe_set_return(dsl_state, step_names),
{:ok, dsl_state} <- validate_return(dsl_state, step_names),
{:ok, reactor} <- Info.to_struct(dsl_state),
{:ok, reactor} <- Planner.plan(reactor) do
dsl_state =
dsl_state
|> Transformer.eval(
[],
quote do
@doc false
@spec reactor :: Reactor.t()
def reactor, do: unquote(Macro.escape(reactor))
end
)
{:ok, dsl_state}
end
end
defp step_names(dsl_state) do
dsl_state
|> Transformer.get_entities([:reactor])
|> Enum.reject(&is_struct(&1, Dsl.Input))
|> Enum.map(& &1.name)
|> case do
[] ->
{:error,
DslError.exception(
module: Transformer.get_persisted(dsl_state, :module),
path: [:reactor],
message: "Reactor contains no steps"
)}
names ->
with :ok <- assert_unique_step_names(names, dsl_state) do
{:ok, names}
end
end
end
defp maybe_set_return(dsl_state, step_names) do
case Transformer.get_option(dsl_state, [:reactor], :return) do
nil ->
dsl_state =
dsl_state
|> Transformer.set_option([:reactor], :return, List.last(step_names))
{:ok, dsl_state}
_ ->
{:ok, dsl_state}
end
end
defp validate_return(dsl_state, step_names) do
name = Transformer.get_option(dsl_state, [:reactor], :return)
if name in step_names do
{:ok, dsl_state}
else
{:error,
DslError.exception(
module: Transformer.get_persisted(dsl_state, :module),
path: [:reactor],
message: "Return value `#{inspect(name)}` does not correspond with an existing step"
)}
end
end
end