{"id":13508556,"url":"https://github.com/vic/pit","last_synced_at":"2025-09-23T13:50:23.505Z","repository":{"id":57533736,"uuid":"70188732","full_name":"vic/pit","owner":"vic","description":"Elixir macro for extracting or transforming values inside a pipe flow.","archived":false,"fork":false,"pushed_at":"2025-07-15T04:33:14.000Z","size":26,"stargazers_count":29,"open_issues_count":1,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-08-19T04:10:18.940Z","etag":null,"topics":["elixir","error-handling","pipe"],"latest_commit_sha":null,"homepage":"https://hex.pm/packages/pit","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","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":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-10-06T20:05:00.000Z","updated_at":"2025-07-15T04:33:18.000Z","dependencies_parsed_at":"2024-05-01T17:13:24.584Z","dependency_job_id":"17624110-6462-463d-8c4a-1ba92f25473a","html_url":"https://github.com/vic/pit","commit_stats":{"total_commits":23,"total_committers":3,"mean_commits":7.666666666666667,"dds":"0.13043478260869568","last_synced_commit":"589d72d4c3ab54a2d13db7d0ed3ed9f6fb474b45"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/vic/pit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vic%2Fpit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vic%2Fpit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vic%2Fpit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vic%2Fpit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vic","download_url":"https://codeload.github.com/vic/pit/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vic%2Fpit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":276588235,"owners_count":25668825,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-23T02:00:09.130Z","response_time":73,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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","pipe"],"created_at":"2024-08-01T02:00:54.746Z","updated_at":"2025-09-23T13:50:23.462Z","avatar_url":"https://github.com/vic.png","language":"Elixir","funding_links":[],"categories":["Macros"],"sub_categories":[],"readme":"# Down the pit\n\n\u003ca href=\"https://travis-ci.org/vic/pit\"\u003e\u003cimg src=\"https://travis-ci.org/vic/pit.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\n## Installation\n\n[Available in Hex](https://hex.pm/packages/pit), the package can be installed as:\n\n  1. Add `pit` to your list of dependencies in `mix.exs`:\n\n```elixir\n  def deps do\n    [{:pit, \"~\u003e 1.2.0\"}]\n  end\n```\n\n## Usage\n\nThe `pit` macro lets you pipe value transformations by pattern matching\non data as it is passed down the pipe.\n\nThe syntax for transforming values is `expression |\u003e pit(value \u003c- pattern)`.\n\nBy default if a value does not match the pattern, `pit` simply passes down\nthe value it was given. You can however enforce the pattern\nto match by using `pit!` which will raise an error on mismatch. Or you\ncan provide an `else:` option to `pit` to handle the mismatch yourself.\n\nSee the following examples:\n\n## Examples\n\n```elixir\n\niex\u003e # Pipe a value if a tagged tuple matches\niex\u003e import Pit\n...\u003e {:ok, \"hello\"}\n...\u003e   |\u003e pit(ok: String.length)\n5\n\niex\u003e # does not pipe if tagged tuple does not match\niex\u003e import Pit\n...\u003e {:error, \"hello\"}\n...\u003e   |\u003e pit(ok: String.length)\n{:error, \"hello\"}\n\n\niex\u003e # pit! raises on tagged tuple mismatch\niex\u003e import Pit\n...\u003e {:error, \"hello\"}\n...\u003e   |\u003e pit!(ok: String.length, yes: String.length)\n** (Pit.PipedValueMismatch) expected piped value to be a tagged tuple with one of keys `[:ok, :yes]` but got `{:error, \"hello\"}`\n\n\niex\u003e # this example transforms an ok tuple\niex\u003e import Pit\n...\u003e value = {:ok, 11}\n...\u003e value\n...\u003e   |\u003e pit(n * 2 \u003c- {:ok, n})\n22\n\n\niex\u003e # If the value does not match, no transformation is made.\niex\u003e import Pit\n...\u003e value = {:ok, :hi}\n...\u003e value\n...\u003e   |\u003e pit(n * 2 \u003c- {:ok, n} when is_number(n))\n{:ok, :hi}\n\n\niex\u003e # You can force the pattern to match by using `pit!`\niex\u003e import Pit\n...\u003e value = {:ok, :hi}\n...\u003e value\n...\u003e   |\u003e pit!(n * 2 \u003c- {:ok, n} when is_number(n))\n** (Pit.PipedValueMismatch) expected piped value to match `{:ok, n} when is_number(n)` but got `{:ok, :hi}`\n\n\niex\u003e # The following will ensure there are no errors on\niex\u003e # the response and double the count value from data.\niex\u003e import Pit\n...\u003e response = {:ok, %{data: %{\"count\" =\u003e 10}, errors: []}}\n...\u003e response\n...\u003e    |\u003e pit!(data \u003c- {:ok, %{errors: [], data: data}})\n...\u003e    |\u003e pit(count * 2 \u003c- %{\"count\" =\u003e count})\n20\n\n\niex\u003e # The pattern can be negated with `not` or `!`.\niex\u003e # in this case raise if an error tuple is found.\niex\u003e import Pit\n...\u003e response = {:cool, 22}\n...\u003e response\n...\u003e    |\u003e pit!(not {:error, _})\n...\u003e    |\u003e pit(n \u003c- {_, n})\n22\n\n\niex\u003e # should raise when using `pit!`\niex\u003e import Pit\n...\u003e response = {:error, :not_found}\n...\u003e response\n...\u003e    |\u003e pit!(not {:error, _})\n...\u003e    |\u003e pit(n \u003c- {_, n})\n** (Pit.PipedValueMismatch) did not expect piped value to match `{:error, _}` but got `{:error, :not_found}`\n\n\niex\u003e # also, when a guard fails an error is raised\niex\u003e import Pit\n...\u003e response = {:ok, 22}\n...\u003e response\n...\u003e    |\u003e pit!({:ok, n} when n \u003e 30)\n...\u003e    |\u003e pit(n \u003c- {:ok, n})\n** (Pit.PipedValueMismatch) expected piped value to match `{:ok, n} when n \u003e 30` but got `{:ok, 22}`\n\n\niex\u003e # If you use `pit!/1` at the final of your pipe, it will\niex\u003e # extract the value that caused the mismatch.\niex\u003e import Pit\n...\u003e value = {:error, 11}\n...\u003e value\n...\u003e   |\u003e pit!({:ok, _})  # raises Pit.PipedValueMismatch\n...\u003e   |\u003e Yeah.got_it     # never gets executed\n...\u003e   |\u003e pit!            # rescue value from PipedValueMismatch\n{:error, 11}\n\n\niex\u003e # The `tag:` option lets you create a tagged tuple.\niex\u003e # Tagging mismatch values can be useful for example to know which\niex\u003e # pipe stage was the one that failed.\niex\u003e import Pit\n...\u003e user = nil # ie. Repo.get_by User, email: \"nick@cage.face\"\n...\u003e user\n...\u003e   |\u003e pit!(not nil, tag: :user) # raises Pit.PipedValueMismatch\n...\u003e   |\u003e User.avatar_url           # never gets executed\n...\u003e   |\u003e pit!                      # unwraps value from PipedValueMismatch\n{:user, nil}\n\n\niex\u003e # Tags also apply on matching patterns.\niex\u003e import Pit\n...\u003e user = {:ok, 21} # ie. Universe.so_so_answer\n...\u003e user\n...\u003e   |\u003e pit!(x * 2 \u003c- {:ok, x}, tag: :answer)\n{:answer, 42}\n\n\niex\u003e # You can provide a default value in case of mismatch\niex\u003e import Pit\n...\u003e response = {:error, :not_found}\n...\u003e response\n...\u003e    |\u003e pit({:ok, _}, else: {:ok, :default})\n...\u003e    |\u003e pit(n \u003c- {:ok, n})\n:default\n\n\niex\u003e # Or you can pipe the mismatch value to other pipe using `else_pipe:` option\niex\u003e # and get the value down a more interesting transformation flow.\niex\u003e import Pit\n...\u003e response = {:ok, \"hello\"}\n...\u003e response\n...\u003e   |\u003e pit({:ok, n} when is_integer(n),\n...\u003e        do: {:ok, :was_integer, n},\n...\u003e        else_pipe: pit(s \u003c- {:ok, s} when is_binary(s)) |\u003e String.length |\u003e pit({:ok, :was_string, len} \u003c- len))\n...\u003e   |\u003e pit(x * 2 \u003c- {:ok, _, x})\n10\n\n\niex\u003e # Both `do_pipe` and `else_pipe` if given the `:it` atom just pass the value down\niex\u003e import Pit\n...\u003e {:error, 22} |\u003e pit({:ok, _}, else_pipe: :it)\n{:error, 22}\n\niex\u003e import Pit\n...\u003e {:ok, 22} |\u003e pit({:ok, _}, do_pipe: :it)\n{:ok, 22}\n\n\niex\u003e # The do form can take a block using bound variables.\niex\u003e import Pit\n...\u003e {:ok, 22}\n...\u003e |\u003e pit {:ok, n} do\n...\u003e    x = n / 11\n...\u003e    x * 2\n...\u003e end\n4.0\n\n\niex\u003e # You can omit parens even with negated pattern\niex\u003e import Pit\n...\u003e {:failure, :nop}\n...\u003e |\u003e pit not {:ok, _} do\n...\u003e   \"Noup\"\n...\u003e end\n...\u003e |\u003e pit {:ok, _} do\n...\u003e   \"Yeah\"\n...\u003e end\n\"Noup\"\n\n\niex\u003e # You can of course provide both do/else\niex\u003e import Pit\n...\u003e {:error, :nop}\n...\u003e |\u003e pit {:ok, _} do\n...\u003e   \"Yeah\"\n...\u003e else\n...\u003e   \"Noup\"\n...\u003e end\n\"Noup\"\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvic%2Fpit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvic%2Fpit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvic%2Fpit/lists"}