Taco v0.1.0 Taco View Source

Composition and error handling of sequential computations, similar to Ecto.Multi

Taco allows to create a chain of actions which might either succeed, fail, or halt the execution of further actions in the pipeline.

Let’s start with an example!

number = 2

Taco.new()
|> Taco.then(:add, fn _ -> {:ok, number + 3} end)
|> Taco.then(:multiply, fn %{add: n} -> {:ok, n * 2} end)
|> Taco.run()

{:ok, :multiply, 10}

We chain two actions - :add and :multiply. Each action receives the results of previous actions in a map (first action receives an empty map), and (in this example) returns an {:ok, result} tuple, which means that computation was successful. Calling Taco.run/1 on such a pipeline returns a tagged result of the last action.

Note that no actions are executed until you call Taco.run/1. You can pass the taco around and run it only when the results are needed.

Actions

Actions are functions which take a map of results of previous actions as an argument. They are executed in the order Taco.then/3 is called. There are three valid return values of an action:

  • {:ok, result} - the action was successful. result will be put in the map of all the results and passed to to the next action in the pipeline, or Taco.run/1 will return {:ok, tag, result} if it was the last action in the pipeline
  • {:halt, result} - the action was successful, but further actions won’t be executed. Taco.run/1 will return immediately with the {:ok, tag, result} tuple
  • {:error, error} - the action failed. Taco.run/1 will return immediately with the {:error, tag, error, results_so_far} tuple. results_so_far is the map of results of all the actions completed before the failing one

Examples

Successful pipeline

iex> number = 2
iex> Taco.new()
...> |> Taco.then(:add, fn _ -> {:ok, number + 3} end)
...> |> Taco.then(:multiply, fn %{add: n} -> {:ok, n * 2} end)
...> |> Taco.run()
{:ok, :multiply, 10}

Halting pipeline

iex> number = 2
iex> Taco.new()
...> |> Taco.then(:add, fn _ -> {:halt, number + 3} end)
...> |> Taco.then(:multiply, fn %{add: n} -> {:ok, n * 2} end)
...> |> Taco.run()
{:ok, :add, 5}

Failing pipeline

iex> number = 2
iex> Taco.new()
...> |> Taco.then(:add, fn _ -> {:ok, number + 3} end)
...> |> Taco.then(:multiply, fn _ -> {:error, "boom!"} end)
...> |> Taco.then(:subtract, fn %{multiply: n} -> {:ok, n - 2} end)
...> |> Taco.run()
{:error, :multiply, "boom!", %{add: 5}}

Link to this section Summary

Functions

Returns a fresh, new taco

Executes the pipeline of actions present in the taco

Appends the action to the pipeline of the taco

Link to this section Types

Link to this type action() View Source
action() :: (results_so_far :: results -> action_ret)
Link to this type action_ret() View Source
action_ret ::
  {:ok, result} |
  {:halt, result} |
  {:error, error}
Link to this type error() View Source
error() :: term
Link to this type result() View Source
result() :: term
Link to this type results() View Source
results() :: %{optional(tag) => result}

Link to this section Functions

Returns a fresh, new taco

Link to this function run(taco) View Source
run(t) ::
  {:ok, tag, result} |
  {:error, tag, error, results_so_far :: results}

Executes the pipeline of actions present in the taco

Raises ArgumentError when no actions are present in the taco.

Link to this function then(taco, tag, action) View Source
then(t, tag, action) :: t

Appends the action to the pipeline of the taco

Raises ArgumentError when:

  • tag is not an atom
  • action is not a 1-arity function
  • action with the given tag is already present

See also “Examples” section of documentation for Taco module.