Skip to content
Pipe elixir functions that match {:ok,_}, {:error,_} tuples or custom patterns.
Elixir
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
config
lib
test
.gitignore
README.md
mix.exs
mix.lock

README.md

Ok Jose

A tiny library for piping function return values on a given pattern like the erlang idiom {:ok, _} and {:error, _} tuples.

You can also define your own pattern-matched pipes besides ok and error.

Also, checkout happy

Installation

  1. Add ok_jose to your list of dependencies in mix.exs:
        def deps do
          [{:ok_jose, "~> 2.0.0"}]
        end

Motivation

A lot of erlang libraries follow the convention of returning {:ok, _} and {:error, _} tuples to denote success or failure.

This library is my try at having a beautiful syntax for a happy pipe, that is, a pipe that expects {:ok, _} tuples to be returned by each piped function. If any piped function returns a non matched value, the remaining functions expecting an {:ok, _} value wont get executed.

So, for example, the following code

filename
|> File.read()
|> case do
  {:ok, content} ->
    content |> Poison.Parser.parse()
  {:error, _} = error -> error
end

can be written as:

filename |> File.read |> Poison.Parser.parse |> ok

or alternatively:

ok(filename |> File.read |> Poison.Parser.parse)

Usage

use OkJose

Provides you with the following macros: ok, ok!, error, error!

use OkJose.Pipe

which provides you the defpipe macro.

ok/1

Pipes values into functions as long as they match {:ok, _}

{:ok, v} |> f |> g |> ok

ok!/1

Pipes values into functions but if at any point a value does not match {:ok, _} raises a match error.

defpipe

Allows you to define custom pipe patterns, for example the previous ok!, macro is defined like:

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

The do block of defpipe has the same form as the elixir case expression.

So for example, you may define a pipe to work on kittens only:

defpipe purr do
  c = %Kitten{} -> c
  t = %Tiger{domesticated: true} -> t
end

Example

ok math
def dup(x), do: {:ok, x * 2}
def nop(x), do: {:error, x}

{:ok, 12} |> dup |> dup |> ok # => {:ok, 48}
{:ok, 24} |> nop |> dup |> ok # => {:error, 24}

{:ok, 24} |> dup |> ok! # => 48
{:ok, 24} |> nop |> dup |> ok! # raises
kittens
defpipe ok_kitten do
  k = %Kitten{} -> k
  t = %Tiger{domesticated: true} -> t
end

def purr(%Kitten{}), do: "purr"
def purr(%Tiger{}), do: "PuRRR"

%Kitten{} |> purr |> ok_kitten #=> "purr"
ok_kitten( %Doggie{} |> purr ) #=> %Doggie{}


# using do/end syntax
# block executed only for matching kittens
%Kitten{} |> (ok_kitten do
  k -> purr(k)
end)

About ok

I wanted name this library ok, but the hex package name was already taken. So I just wanted to make a tribute to @josevalim.

Actually both projects are trying to solve the same issue. But I think this one has an easier syntax that consist of just piping to ok

Also, checkout happy

Is it any good?

Yes

マクロス Makurosu

[Elixir macros,] The things I do for beautiful code ― George Martin, Game of Thrones

#myelixirstatus #FridayLiterally

Something went wrong with that request. Please try again.