ok_jose v3.0.0 OkJose.Pipe

Functions for piping tagged tuples

Link to this section Summary

Functions

Pipes value when a match clause evalutes to {true, value}

Lets you define a named pipe

Pipes values down while they match {:error, value}

Sames as error/2 but raises on value mismatch

Pipes values as long as the given predicate is true

Pipes values down while they match {:ok, value}

Same as ok/2 but raises on value mismatch

Tags a value with an atom inside a pipe

Tags the value returned by a pipe fragment

Yields its piped value into a side-effect function

Shorthand for Pipe.tap on ok tuples

Untags a piped value if its tagged with tag. Othewrise the piped value is returned as is

Like untag/2 but produces a match error if value is not tagged with tag

Link to this section Functions

Link to this macro cond(pipe, clauses) (macro)

Pipes value when a match clause evalutes to {true, value}

Because cond/2 takes a do block with match clauses, be sure to suround it with parens.

Every clause must return a tuple like {boolean, payload} if the boolean value is true, the payload is passed down the pipe, otherwise it’s returned and pipe is execution is halted.

iex> use OkJose
...> 1
...> |> fn "1" -> :one end.()
...> |> String.length
...> |> fn _ -> 99 end.()
...> |> (Pipe.cond do
...>    x when x < 2 -> {true, to_string(x)}
...>    x when is_atom(x) -> {true, to_string(x)}
...>    anything -> {false, anything}
...> end)
3

if/2 is implemented like:

(Pipe.cond do
  value -> {predicate.(value), value}
end)
Link to this macro defpipe(name, clauses) (macro)

Lets you define a named pipe

The ok/2 pipe is defined like:

defpipe ok do
  {:ok, value} -> value
end

But you are not limited to :ok atoms

defmodule Maybe do
  use OkJose

  defpipe just do
    {:just, :me} -> "jordan"
    {:just, value} -> value
    {:ok, value} -> value
  end
end

Once defined, you can use pipe to your new named macro. When a non-matching value is found, the pipe execution is stoped.

assert "Jordan" ==
  {:just, :me}
  |> String.capitalize
  |> String.reverse
  |> Maybe.just

If the pipe name ends with a bang like ok! an error is raised on mismatch

defpipe ok! do
  {:ok, value} -> value
end
Link to this macro error(code) (macro)

Pipes values down while they match {:error, value}

Link to this macro error(prev, code) (macro)
Link to this macro error!(code) (macro)

Sames as error/2 but raises on value mismatch

Link to this macro error!(prev, code) (macro)
Link to this macro if(pipe, predicate) (macro)

Pipes values as long as the given predicate is true

iex> use OkJose
...>
...> [1]
...> |> fn x -> [5 | x] end.()
...> |> fn x -> [2 | x] end.()
...> |> fn x -> [9 | x] end.()
...> |> Pipe.if(fn x -> Enum.sum(x) < 6 end)
[5, 1]
Link to this macro ok(code) (macro)

Pipes values down while they match {:ok, value}

iex> use OkJose
...> {:ok, 10}
...> |> fn x -> x * 20 end.()
...> |> Pipe.ok
200

iex> use OkJose
...> {:ok, 10}
...> |> fn x -> {:error, x + 10} end.()
...> |> fn x -> {:ok, x + 2} end.()
...> |> Pipe.ok
{:error, 20}
Link to this macro ok(prev, code) (macro)
Link to this macro ok!(code) (macro)

Same as ok/2 but raises on value mismatch

Link to this macro ok!(prev, code) (macro)
Link to this function tag(value, tag)

Tags a value with an atom inside a pipe

iex> use OkJose
...> 20
...> |> Pipe.tag(:ok)
{:ok, 20}
Link to this macro tag(piped_value, tag, pipe_fragment) (macro)

Tags the value returned by a pipe fragment.

This macro is useful for working with functions that are not tagged-tuple aware, that is, they return just plain values, like Map.put/3 which returns a Map data structure.

iex> use OkJose
...> %{a: 1}
...> |> Pipe.tag(:ok, Map.put(:b, 2))
{:ok, %{a: 1, b: 2}}
Link to this macro tap(pipe, arg) (macro)

Yields its piped value into a side-effect function

The return value of the side function is ignored. Continues the pipe with the original value tagged with a new atom

iex> use OkJose
...> {:ok, 1}
...> |> Pipe.tap({:foo, IO.inspect})
...> |> Pipe.ok
{:foo, 1} # side effect printed 1
Link to this macro tap_ok(pipe, expr) (macro)

Shorthand for Pipe.tap on ok tuples

 value
 |> Pipe.tap({:ok, expr})
Link to this function untag(tagged, tag)

Untags a piped value if its tagged with tag. Othewrise the piped value is returned as is.

iex> use OkJose
...> {:ok, 22}
...> |> Pipe.untag(:ok)
22

iex> use OkJose
...> {:error, 33}
...> |> Pipe.untag(:ok)
{:error, 33}
Link to this function untag!(tagged, tag)

Like untag/2 but produces a match error if value is not tagged with tag.

iex> use OkJose
...> {:error, 44}
...> |> Pipe.untag!(:ok)
** (CaseClauseError) no case clause matching: {:error, 44}