View Source PipeHelpers (PipeHelpers v1.4.0)
Helpers for piping data. The provided helpers can be grouped into two categories:
- generate tuples that fit the return type of the containing function
- deal with previous function tuple output without "breaking the pipe"
1-return-tuples-builders
1. Return tuples builders
You can use only the first category to improve readability in your code.
For instance, lets take a typical Phoenix.LiveView code:
def mount(_params, _session, socket) do
socket = assign(socket, my_bool_assign: true)
{:ok, socket}
endWith ok/1, it can be rewritten as:
def mount(_params, _session, socket) do
socket
|> assign( my_bool_assign: true)
|> ok()
endIn addition to the typical {:ok, value} return tuple, the library provides
the most common return types helpers noreply/1 reply/2. Generic helpers
are also provided to build whatever tuple you need with pair/2 and rpair/2.
2-tuple-deconstructors
2. Tuple deconstructors
In some situations, return type incompatibilities prevent you from using an uninterrupted pipe sequence. In this case, the following helpers may help:
2a-generic-unpair
2a Generic unpair
The generic unpair/1 allows you to ignore the first element of the pair
and forward the second for further piping.
2b-only-when-ok-execution
2b Only when "ok" execution
The then_ok/2 provides a promise-like solution to handle 'maybe ok'
results. If the result is an ok-tuple, it executes the function on the second argument
and passes the result forward (i.e. for further piping). If the result is not an
ok-tuple (typically an {:error, message} tuple), it is forwarded directly.
For example, let's take the following (very powerful translator) function:
def translate(source) do
case source do
"ola" -> {:ok, "hello"}
_ -> {:error, "can't translate, sorry"}
end
endAnd the quoting function that you want to pipe into:
def quote(text) do
text
endThe translate/1 output doesn't fit the quote/1 input, so the
following pipe is not possible:
my_source
|> translate()
|> quote()With the then_ok/2 you can handle do:
my_source
|> translate()
|> then_ok("e/1)This pipe will either return the properly quoted translation or the error tuple
generated by the translate/1.
If you intend to successively pipe into more than a single functions after an
{:ok, result}returning function, you need to only have{:ok, result}functions except the last one and always use thethen_ok/2construct until the end. Doing so you can safely do the error management at the end of the pipe using a|> case doirrespective of the function that failed to provide an{:ok, result}output.
The then_on/3 provides similar behaviour with a more generic/powerful pattern
matching on the previous function output.
The functions above have their tap counterpart if the idea is to apply a
conditional side effect without modifying the piped value.
Link to this section Summary
Functions
Wrap into {:cont, state} tuple (phoenix socket format).
Wrap into standard {:error, result} tuple.
Wrap into {:halt, state} tuple (phoenix socket format).
Wrap into {:halt, reply, state} tuple (phoenix socket format).
Wrap into {:noreply, state} tuple (genserver and phoenix socket format).
Wrap into standard {:ok, result} tuple.
If result is an error tuple, execute fun with the right part of result tuple as single argument
and return fun output.
Otherwise, return result as-is.
Wrap into generic tuple pair.
Wrap into {:reply, reply, state} tuple (genserver and phoenix socket format).
Wrap into tuple rpair.
Wrap into {:reply, reply, state} tuple (genserver and phoenix socket format).
Execute fun function only if result is an ok-tuple. Returns the input in any case.
Execute fun function only if the first arument matches the second one (value = result check).
Returns the input in any case.
Then only if condition is true.
If result is an ok tuple, execute fun with the right part of result tuple as single argument
and return fun output.
Otherwise, return result as-is.
Then only if value match. See then_ok/2 and tap_ok/3
Unwrap from a tuple pair.
Unwrap a tuple, but raise if not {:ok, value}
Link to this section Functions
Wrap into {:cont, state} tuple (phoenix socket format).
Wrap into standard {:error, result} tuple.
example
Example
iex> :not_found |> err()
{:error, :not_found}
Wrap into {:halt, state} tuple (phoenix socket format).
Wrap into {:halt, reply, state} tuple (phoenix socket format).
Wrap into {:noreply, state} tuple (genserver and phoenix socket format).
example
Example
iex> state = "gen server state"
...> state |> noreply()
{:noreply, "gen server state"}
Wrap into standard {:ok, result} tuple.
example
Example
iex> socket = "socket"
...> socket |> ok()
{:ok, "socket"}
If result is an error tuple, execute fun with the right part of result tuple as single argument
and return fun output.
Otherwise, return result as-is.
Wrap into generic tuple pair.
example
Example
iex> 1 |> pair(2)
{2, 1}
Wrap into {:reply, reply, state} tuple (genserver and phoenix socket format).
example
Example
iex> state = "gen server state"
...> r = "reply"
...> state |> reply(r)
{:reply, "reply", "gen server state"}
Wrap into tuple rpair.
example
Example
iex> 1 |> rpair(2)
{1, 2}
Wrap into {:reply, reply, state} tuple (genserver and phoenix socket format).
example
Example
iex> state = "gen server state"
...> r = "reply"
...> r |> rreply(state)
{:reply, "reply", "gen server state"}
Execute fun function only if result is an ok-tuple. Returns the input in any case.
The fun argument is a function taking the right part of the ok-tuple
as an optional argument.
example
Example
iex> {:ok, "somedata"} |> tap_ok(fn -> "only executed when {:ok, ...}" end)
{:ok, "somedata"}
iex> {:error, "failed"} |> tap_ok(fn -> "not executed when not {:ok, ...}" end)
{:error, "failed"}
Execute fun function only if the first arument matches the second one (value = result check).
Returns the input in any case.
example
Example
iex> true |> tap_on(true, fn -> "only executed when matching 'true'" end)
true
iex> false |> tap_on(true, fn -> "not executed when not matchin 'true'" end)
false
Then only if condition is true.
If result is an ok tuple, execute fun with the right part of result tuple as single argument
and return fun output.
Otherwise, return result as-is.
example
Example
iex> {:ok, "somedata"} |> then_ok(fn -> "only returned when result argument is {:ok, ...}" end)
"only returned when result argument is {:ok, ...}"
iex> {:error, "failed"} |> then_ok(fn -> "only returned when result argument is {:ok, ...}" end)
{:error, "failed"}
Then only if value match. See then_ok/2 and tap_ok/3
Unwrap from a tuple pair.
example
Example
iex> {:ok, 1} |> unpair()
1
Unwrap a tuple, but raise if not {:ok, value}
example
Example
iex> {:ok, "hello"} |> unwrap!()
"hello"