{"id":13508541,"url":"https://github.com/vic/ok_jose","last_synced_at":"2026-02-22T05:32:49.750Z","repository":{"id":57530302,"uuid":"48339456","full_name":"vic/ok_jose","owner":"vic","description":"Pipe elixir functions that match ok/error tuples or custom patterns.","archived":false,"fork":false,"pushed_at":"2017-11-08T14:15:36.000Z","size":40,"stargazers_count":101,"open_issues_count":2,"forks_count":2,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-12-25T06:08:39.705Z","etag":null,"topics":["elixir","error-handling","monad","pipe"],"latest_commit_sha":null,"homepage":"https://hexdocs.pm/ok_jose/OkJose.Pipe.html","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vic.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-12-20T22:26:27.000Z","updated_at":"2025-12-04T00:21:07.000Z","dependencies_parsed_at":"2022-09-10T11:01:38.113Z","dependency_job_id":null,"html_url":"https://github.com/vic/ok_jose","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/vic/ok_jose","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vic%2Fok_jose","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vic%2Fok_jose/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vic%2Fok_jose/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vic%2Fok_jose/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vic","download_url":"https://codeload.github.com/vic/ok_jose/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vic%2Fok_jose/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29705536,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-22T03:17:42.375Z","status":"ssl_error","status_checked_at":"2026-02-22T03:17:31.622Z","response_time":110,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elixir","error-handling","monad","pipe"],"created_at":"2024-08-01T02:00:54.548Z","updated_at":"2026-02-22T05:32:49.732Z","avatar_url":"https://github.com/vic.png","language":"Elixir","funding_links":[],"categories":["Macros"],"sub_categories":[],"readme":"# Ok Jose\n\n\u003ca href=\"https://travis-ci.org/vic/ok_jose\"\u003e\u003cimg src=\"https://travis-ci.org/vic/ok_jose.svg\"\u003e\u003c/a\u003e\n[![help maintain this lib](https://img.shields.io/badge/looking%20for%20maintainer-DM%20%40vborja-663399.svg)](https://twitter.com/vborja)\n\n\nA tiny library for piping values on a given pattern like the erlang idiom `{:ok, _}` and `{:error, _}` tuples.\n\nYou can also define your own pattern-matched pipes besides `ok` and `error`.\n\nBesides `ok_jose` I've made a couple more of related macro libraries\nthat might be related (or useful depending on your needs and taste):\n\n- [happy](https://github.com/vic/happy) from back before `with` landed elixir 1.2\n- [pit](https://github.com/vic/pit) a kind of pipeable `with`.\n\n## Installation\n\n  1. Add ok_jose to your list of dependencies in `mix.exs`:\n\n```elixir\n  def deps do\n    [{:ok_jose, \"~\u003e 3.0.0\"}]\n  end\n```\n\n## Motivation\n\nA lot of erlang libraries follow the convention of returning `{:ok, _}` and `{:error, _}` tuples to denote \nthe success or failure of a computation. It's my opinion that more people should embrace this convention\non their code, and this library helps by making it easier to pipe values by unwrapping them from the\ntagged tuples.\n\n\nThis library is my try at having a beautiful syntax for a *happy pipe*, that is, a pipe that expects `{:ok, _}`\ntuples to be returned by each piped function.\nIf any piped function returns a non matched value, the remaining functions expecting an `{:ok, _}` value won't get executed.\n\nSo, for example, the following code\n\n```elixir\nfilename\n|\u003e File.read()\n|\u003e case do\n  {:ok, content} -\u003e\n    content |\u003e Poison.Parser.parse()\n  {:error, _} = error -\u003e error\nend\n```\n\ncan be written as:\n\n```elixir\nuse OkJose\n\n{:ok, filename}\n|\u003e File.read\n|\u003e Poison.Parser.parse\n|\u003e Pipe.ok\n```\n\nThe main advantage of the macros defined by OkJose is that you don't need to learn new syntax\nit's just plain old Elixir piping. It's also very easy to define your own, as they are just\ncase clauses.\n\n## Usage\n\nRead the [OkJose.Pipe docs](https://hexdocs.pm/ok_jose/OkJose.Pipe.html) for examples.\n\n### `use OkJose`\n\nProvides you with the `defpipe` macro and aliases `OkJose.Pipe` as `Pipe`\nin the current lexical context.\n\n##### [ok/2](https://hexdocs.pm/ok_jose/OkJose.Pipe.html#ok/2)\n\nPasses values down the pipe as long as they match `{:ok, value}`.\n\n```elixir\n{:ok, filename}\n|\u003e File.read\n|\u003e Poison.Parser.parse\n|\u003e Pipe.ok\n```\n\nsee also \n[ok!/2](https://hexdocs.pm/ok_jose/OkJose.Pipe.html#ok!/2),\n[error/2](https://hexdocs.pm/ok_jose/OkJose.Pipe.html#error/2),\n[error!/2](https://hexdocs.pm/ok_jose/OkJose.Pipe.html#error!/2)\n\n\n##### [defpipe/2](https://hexdocs.pm/ok_jose/OkJose.Pipe.html#defpipe/2)\n\nLets you define a custom pipe, for example, for working with ok\ntuples and also valid ecto changesets.\n\n```elixir\ndefpipe ok_or_valid do\n  {:ok, value} -\u003e value\n  valid = %{valid?: true} -\u003e valid\nend\n\n\n{:ok, %User{}}\n|\u003e cast(params, @required)\n|\u003e validate_required(:email)\n|\u003e Repo.insert\n|\u003e Pipe.tap({:ok, send_welcome_email}) # discard email\n|\u003e ok_or_valid\n# =\u003e {:ok, inserted_user}\n```\n\n##### [if/2](https://hexdocs.pm/ok_jose/OkJose.Pipe.html#if/2),\n\nLets you pipe values as long as they satisfy a function predicate.\nThis can be useful for cases where you need to call functions and\nnot only pattern match on the piped values.\n\n```elixir\n[1]\n|\u003e fn x -\u003e [5 | x] end.()\n|\u003e fn x -\u003e [4 | x] end.()\n|\u003e fn x -\u003e [3 | x] end.()\n|\u003e fn x -\u003e [2 | x] end.()\n|\u003e Pipe.if(fn x -\u003e Enum.sum(x) \u003c 10 end)\n# =\u003e [4, 5, 1]\n```\n##### [cond/2](https://hexdocs.pm/ok_jose/OkJose.Pipe.html#cond/2)\n\nA more generic way to select which values can be passed down the\npipe and which cause the pipe to stop.\n\n```elixir\n{:ok, jwt_token}\n|\u003e User.find_by_jwt\n|\u003e User.new_session\n|\u003e (Pipe.cond do\n  # stop piping if no user found\n  nil -\u003e {false, {:error, :invalid_token}}\n\n  # user gets piped only if not currently logged in\n  {:ok, user = %User{}} -\u003e \n    if User.is_logged_in?(user) do\n      {false, {:error, :already_logged_in}}\n    else\n      {true, user}\n    end\nend)\n```\n\n##### [and more](https://hexdocs.pm/ok_jose/OkJose.Pipe.html)\n\n## About\n\nOkJose was born a while ago, back before we had Elixir 1.0, and before Elixir had its\nown `with` form to deal with this kind of problems. There are a lot of other libraries\nfor dealing with tagged tuples and in general for monads in elixir. I'd recommend you\nto checkout these in particular: \n\n- [`ok`](https://hex.pm/packages/ok) \n  A growing library, also has a list of alternatives at their Readme.\n\n- [`happy`](https://github.com/vic/happy)\n  Work on OkJose lead me to creating happy and later [`happy_with`](https://github.com/vic/happy_with)\n  They are just a bit less-pipeable than OkJose, and more on the spirit of Elixir's `with`\n  \n- [`pit`](https://github.com/vic/pit)\n  A weird one, for transforming and matching data at every pipe step. \n  I don't know what I was thinking while doing it, but maybe it can be of use to someone.\n\n## Is it any good?\n\n[Yes](https://news.ycombinator.com/item?id=3067434)\n\nTake a look at the tests for more code examples.\n\n##### マクロス Makurosu\n\n[[Elixir macros](https://github.com/h4cc/awesome-elixir#macros),] The things I do for beautiful code\n― George Martin, Game of Thrones\n\n[#myelixirstatus](https://twitter.com/hashtag/myelixirstatus?src=hash)\n[#FridayLiterally](http://futurice.com/blog/friday-literally)\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvic%2Fok_jose","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvic%2Fok_jose","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvic%2Fok_jose/lists"}