# SPDX-FileCopyrightText: 2019 ash contributors # # SPDX-License-Identifier: MIT defmodule Ash.Reactor.Dsl.AshStep do @moduledoc """ The ash_step DSL module. See `d:Reactor.step`. """ defstruct __identifier__: nil, arguments: [], async?: true, compensate: nil, guards: [], impl: nil, max_retries: :infinity, name: nil, run: nil, transform: nil, undo: nil, __spark_metadata__: nil alias Reactor.{Dsl, Step} @type t :: %__MODULE__{ arguments: [Dsl.Argument.t()], async?: boolean, compensate: nil | (any, Reactor.inputs(), Reactor.context() -> :ok | :retry | {:continue, any}), guards: [Reactor.Guard.Build.t()], impl: nil | module | {module, keyword}, max_retries: non_neg_integer() | :infinity, name: atom, run: nil | (Reactor.inputs(), Reactor.context() -> {:ok, any} | {:ok, any, [Step.t()]} | {:halt | :error, any}), transform: nil | (any -> any), undo: nil | (any, Reactor.inputs(), Reactor.context() -> :ok | :retry | {:error, any}), __identifier__: any, __spark_metadata__: Spark.Dsl.Entity.spark_meta() } @doc false def __entity__, do: %Spark.Dsl.Entity{ name: :ash_step, describe: """ Specifies a Ash.Reactor step. This is basically a wrapper around `Reactor.step`, in order to handle any returned notifications from the run step/function. See the `Reactor.Step` behaviour for more information. """, examples: [ """ ash_step :create_post, MyApp.CreatePostStep do argument :title, input(:title) end """, """ ash_step :create_post do argument :title, input(:title) run fn %{title: title}, _ -> MyApp.Post.create(title, return_notifications?: true) end end """ ], args: [:name, {:optional, :impl}], target: __MODULE__, identifier: :name, no_depend_modules: [:impl], entities: [ arguments: [Dsl.Argument.__entity__(), Dsl.WaitFor.__entity__()], guards: [Reactor.Dsl.Guard.__entity__(), Reactor.Dsl.Where.__entity__()] ], recursive_as: :steps, schema: [ name: [ type: :atom, required: true, doc: """ A unique name for the step. Used when choosing the return value of the Reactor and for arguments into other steps. """ ], impl: [ type: {:or, [{:spark_behaviour, Step}, nil]}, required: false, doc: """ A module that implements the `Reactor.Step` behaviour that provides the implementation. """ ], run: [ type: {:or, [{:mfa_or_fun, 1}, {:mfa_or_fun, 2}]}, required: false, doc: """ Provide an anonymous function which implements the `run/3` callback. Cannot be provided at the same time as the `impl` argument. """ ], undo: [ type: {:or, [{:mfa_or_fun, 1}, {:mfa_or_fun, 2}, {:mfa_or_fun, 3}]}, required: false, doc: """ Provide an anonymous function which implements the `undo/4` callback. Cannot be provided at the same time as the `impl` argument. """ ], compensate: [ type: {:or, [{:mfa_or_fun, 1}, {:mfa_or_fun, 2}, {:mfa_or_fun, 3}]}, required: false, doc: """ Provide an anonymous function which implements the `undo/4` callback. Cannot be provided at the same time as the `impl` argument. """ ], max_retries: [ type: {:or, [{:in, [:infinity]}, :non_neg_integer]}, required: false, default: :infinity, doc: """ The maximum number of times that the step can be retried before failing. Only used when the result of the `compensate/4` callback is `:retry`. """ ], async?: [ type: :boolean, required: false, default: true, doc: """ When set to true the step will be executed asynchronously via Reactor's `TaskSupervisor`. """ ], transform: [ type: {:or, [{:spark_function_behaviour, Step, {Step.TransformAll, 1}}, nil]}, required: false, default: nil, doc: """ An optional transformation function which can be used to modify the entire argument map before it is passed to the step. """ ] ] } end