Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions lib/reactor.ex
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ defmodule Reactor do
defstruct context: %{},
description: nil,
id: nil,
input_descriptions: %{},
inputs: [],
intermediate_results: %{},
middleware: [],
Expand Down Expand Up @@ -139,8 +138,7 @@ defmodule Reactor do
context: context,
description: nil | String.t(),
id: any,
input_descriptions: %{atom => String.t()},
inputs: [atom],
inputs: [Reactor.Input.t()],
intermediate_results: %{any => any},
middleware: [Reactor.Middleware.t()],
plan: nil | Graph.t(),
Expand Down
2 changes: 1 addition & 1 deletion lib/reactor/builder/compose.ex
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ defmodule Reactor.Builder.Compose do
end

defp reactor_inputs(reactor) when is_struct(reactor),
do: {:ok, MapSet.new(reactor.inputs)}
do: {:ok, MapSet.new(reactor.inputs, & &1.name)}

defp reactor_inputs(reactor) when is_atom(reactor) do
with {:ok, reactor} <- Reactor.Info.to_struct(reactor) do
Expand Down
58 changes: 23 additions & 35 deletions lib/reactor/builder/input.ex
Original file line number Diff line number Diff line change
Expand Up @@ -38,38 +38,34 @@ defmodule Reactor.Builder.Input do
@doc """
Add a named input to the reactor.
"""
@spec add_input(Reactor.t(), any, options) :: {:ok, Reactor.t()} | {:error, any}
def add_input(reactor, name, options) do
case validate_options(options) do
{:ok, options} when is_nil(options.transform) ->
reactor =
reactor
|> do_add_input(name)
|> maybe_add_description(name, options.description)
@spec add_input(Reactor.t(), any, options | transform) :: {:ok, Reactor.t()} | {:error, any}
def add_input(reactor, name, nil), do: add_input(reactor, name, [])

{:ok, reactor}

{:ok, options} ->
reactor =
reactor
|> do_add_input(name)
|> add_input_transform(name, options.transform)
|> maybe_add_description(name, options.description)

{:ok, reactor}
def add_input(reactor, name, options) when is_list(options) do
with {:ok, options} <- Spark.Options.validate(options, @options) do
reactor =
reactor
|> do_add_input(name, options)
|> maybe_add_input_transform(name, options[:transform])

{:error, reason} ->
{:error, reason}
{:ok, reactor}
end
end

defp do_add_input(reactor, name), do: %{reactor | inputs: [name | reactor.inputs]}
defp maybe_add_description(reactor, _name, nil), do: reactor
def add_input(reactor, name, transform), do: add_input(reactor, name, transform: transform)

defp do_add_input(reactor, name, options) do
input = %Reactor.Input{
name: name,
description: options[:description]
}

%{reactor | inputs: [input | reactor.inputs]}
end

defp maybe_add_description(reactor, name, description),
do: %{reactor | input_descriptions: Map.put(reactor.input_descriptions, name, description)}
defp maybe_add_input_transform(reactor, _name, nil), do: reactor

defp add_input_transform(reactor, name, {module, options} = transform)
defp maybe_add_input_transform(reactor, name, {module, options} = transform)
when is_atom(module) and is_list(options) do
transform_step = %Step{
arguments: [Argument.from_input(:value, name)],
Expand All @@ -84,14 +80,6 @@ defmodule Reactor.Builder.Input do
%{reactor | steps: [transform_step | reactor.steps]}
end

defp add_input_transform(reactor, name, transform),
do: add_input_transform(reactor, name, {Step.Transform, fun: transform})

defp validate_options(options) when is_list(options) do
with {:ok, options} <- Spark.Options.validate(options, @options) do
{:ok, Map.new(options)}
end
end

defp validate_options(transform), do: validate_options(transform: transform)
defp maybe_add_input_transform(reactor, name, transform),
do: maybe_add_input_transform(reactor, name, {Step.Transform, fun: transform})
end
4 changes: 2 additions & 2 deletions lib/reactor/executor/init.ex
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,11 @@ defmodule Reactor.Executor.Init do
end

defp validate_inputs(reactor, inputs) do
valid_input_names = MapSet.new(reactor.inputs)
valid_input_names = MapSet.new(reactor.inputs, & &1.name)
provided_input_names = inputs |> Map.keys() |> MapSet.new()

if MapSet.subset?(valid_input_names, provided_input_names) do
{:ok, Map.take(inputs, reactor.inputs)}
{:ok, Map.take(inputs, Enum.to_list(valid_input_names))}
else
missing_inputs =
valid_input_names
Expand Down
11 changes: 11 additions & 0 deletions lib/reactor/input.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
defmodule Reactor.Input do
@moduledoc """
Reactor's internal representation for inputs.
"""
defstruct [:name, :description]

@type t :: %__MODULE__{
name: atom,
description: nil | String.t()
}
end
10 changes: 5 additions & 5 deletions lib/reactor/mermaid/reactor.ex
Original file line number Diff line number Diff line change
Expand Up @@ -52,24 +52,24 @@ defmodule Reactor.Mermaid.Reactor do
|> map_while_ok(&generate_input(&1, reactor, options))
end

defp generate_input(input_name, reactor, options) do
id = mermaid_id({reactor.id, input_name}, :input)
defp generate_input(input, reactor, options) do
id = mermaid_id({reactor.id, input.name}, :input)

content =
if options[:describe?] do
[
id,
">\"`",
"**Input ",
to_string(input_name),
to_string(input.name),
"**",
"\n",
md_escape(Map.get(reactor.input_descriptions, input_name)),
md_escape(input.description),
"`\"]",
"\n"
]
else
[id, ">\"Input ", to_string(input_name), "\"]\n"]
[id, ">\"Input ", to_string(input.name), "\"]\n"]
end

{:ok, %Node{id: id, pre: content}}
Expand Down
2 changes: 1 addition & 1 deletion lib/reactor/step/around/mermaid.ex
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ defmodule Reactor.Step.Around.Mermaid do
links =
reactor.inputs
|> Enum.map(fn input ->
[node.id, "-->", mermaid_id({reactor.id, input}, :input), "\n"]
[node.id, "-->", mermaid_id({reactor.id, input.name}, :input), "\n"]
end)
|> Enum.concat([inner_return_id, "-->", node.id, "\n"])

Expand Down
2 changes: 1 addition & 1 deletion lib/reactor/step/compose/mermaid.ex
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ defmodule Reactor.Step.Compose.Mermaid do
links =
reactor.inputs
|> Enum.map(fn input ->
[node.id, "-->", mermaid_id({reactor.id, input}, :input), "\n"]
[node.id, "-->", mermaid_id({reactor.id, input.name}, :input), "\n"]
end)
|> Enum.concat([inner_return_id, "-->", node.id, "\n"])

Expand Down
2 changes: 1 addition & 1 deletion lib/reactor/step/group/mermaid.ex
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ defmodule Reactor.Step.Group.Mermaid do
links =
reactor.inputs
|> Enum.map(fn input ->
[node.id, "-->", mermaid_id({reactor.id, input}, :input), "\n"]
[node.id, "-->", mermaid_id({reactor.id, input.name}, :input), "\n"]
end)
|> Enum.concat([inner_return_id, "-->", node.id, "\n"])

Expand Down
2 changes: 1 addition & 1 deletion lib/reactor/step/map/mermaid.ex
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ defmodule Reactor.Step.Map.Mermaid do
links =
reactor.inputs
|> Enum.map(fn input ->
[node.id, "-->", mermaid_id({reactor.id, input}, :input), "\n"]
[node.id, "-->", mermaid_id({reactor.id, input.name}, :input), "\n"]
end)
|> Enum.concat([inner_return_id, "-->", node.id, "\n"])

Expand Down
2 changes: 1 addition & 1 deletion lib/reactor/step/recurse/mermaid.ex
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ defmodule Reactor.Step.Recurse.Mermaid do
links =
reactor.inputs
|> Enum.map(fn input ->
[node.id, "-->", mermaid_id({reactor.id, input}, :input), "\n"]
[node.id, "-->", mermaid_id({reactor.id, input.name}, :input), "\n"]
end)
|> Enum.concat([inner_return_id, "-->", node.id, "\n"])

Expand Down
6 changes: 3 additions & 3 deletions test/reactor/builder/input_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ defmodule Reactor.Builder.InputTest do
Builder.new()
|> Input.add_input(:marty, nil)

assert :marty in reactor.inputs
assert %Reactor.Input{name: :marty} in reactor.inputs
assert [] = reactor.steps
end

Expand All @@ -18,7 +18,7 @@ defmodule Reactor.Builder.InputTest do
Builder.new()
|> Input.add_input(:marty, &Function.identity/1)

assert :marty in reactor.inputs
assert %Reactor.Input{name: :marty} in reactor.inputs
assert [step] = reactor.steps

assert step.name == {:__reactor__, :transform, :input, :marty}
Expand All @@ -30,7 +30,7 @@ defmodule Reactor.Builder.InputTest do
Builder.new()
|> Input.add_input(:marty, {Step.Transform, fun: &Function.identity/1})

assert :marty in reactor.inputs
assert %Reactor.Input{name: :marty} in reactor.inputs
assert [step] = reactor.steps

assert step.name == {:__reactor__, :transform, :input, :marty}
Expand Down
4 changes: 2 additions & 2 deletions test/reactor/builder_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ defmodule Reactor.BuilderTest do

test "when the input doesn't have a transformer, it adds the input" do
{:ok, reactor} = add_input(new(), :marty)
assert :marty in reactor.inputs
assert %Reactor.Input{name: :marty} in reactor.inputs
end

test "when the input has a transformer it adds a transform step and the input" do
{:ok, reactor} = add_input(new(), :marty, &String.upcase/1)
assert :marty in reactor.inputs
assert %Reactor.Input{name: :marty} in reactor.inputs
[transform_step] = reactor.steps

assert transform_step.name == {:__reactor__, :transform, :input, :marty}
Expand Down
2 changes: 1 addition & 1 deletion test/reactor/dsl/input_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,6 @@ defmodule Reactor.Dsl.InputTest do

reactor = Reactor.Info.to_struct!(InputDescriptionReactor)

assert %{input: "An example input"} = reactor.input_descriptions
assert ["An example input"] = Enum.map(reactor.inputs, & &1.description)
end
end