Packages

Pipe result tuples {:ok, value} all the way

Current section

Files

Jump to
railway lib railway.ex
Raw

lib/railway.ex

defmodule Railway do
@moduledoc """
Railway pipe operator.
"""
defmacro __using__(_opts) do
quote do
import unquote(__MODULE__), only: [~>>: 2]
end
end
@doc """
The ~>> operator introduces the value of an {:ok, value} tuple on the left-hand side
as the first argument to the function call on the right-hand side.
If the tuple on the left-hand side is anything different from {:ok, value} like {:error, reason}
the ~>> operator will just return the left-hand side and not execute the function call on the right.
If the expression on the left-hand side is not a tuple, the ~>> operator will behave just like |> does.
## Examples
iex> use Railway
iex> {:ok, "some string"} ~>> String.upcase()
"SOME STRING"
iex> use Railway
iex> {:error, "some string"} ~>> String.upcase()
{:error, "some string"}
"""
def unwrap({:ok, value}, fun), do: fun.(value)
def unwrap({term, _} = value, _fun) when is_atom(term), do: value
def unwrap(value, fun), do: fun.(value)
defmacro left ~>> right do
quote do
Railway.unwrap(
unquote(left),
fn value -> unquote(Macro.pipe(quote(do: value), right, 0)) end
)
end
end
end