{"id":17398963,"url":"https://github.com/jcomellas/ex_const","last_synced_at":"2025-10-15T02:16:19.017Z","repository":{"id":57500126,"uuid":"91858698","full_name":"jcomellas/ex_const","owner":"jcomellas","description":"Constants and Enumerated Values for Elixir","archived":false,"fork":false,"pushed_at":"2024-05-06T15:19:33.000Z","size":34,"stargazers_count":22,"open_issues_count":1,"forks_count":7,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-25T19:01:39.796Z","etag":null,"topics":["constants","elixir","elixir-library","enumeration"],"latest_commit_sha":null,"homepage":null,"language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jcomellas.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":"2017-05-20T02:03:36.000Z","updated_at":"2024-09-22T20:15:06.000Z","dependencies_parsed_at":"2024-10-31T08:03:08.378Z","dependency_job_id":null,"html_url":"https://github.com/jcomellas/ex_const","commit_stats":{"total_commits":32,"total_committers":1,"mean_commits":32.0,"dds":0.0,"last_synced_commit":"c98c78045d03a347a41d98e5ca70b537a427fbfa"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcomellas%2Fex_const","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcomellas%2Fex_const/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcomellas%2Fex_const/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcomellas%2Fex_const/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jcomellas","download_url":"https://codeload.github.com/jcomellas/ex_const/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247249524,"owners_count":20908212,"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","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":["constants","elixir","elixir-library","enumeration"],"created_at":"2024-10-16T15:03:44.845Z","updated_at":"2025-10-15T02:16:13.974Z","avatar_url":"https://github.com/jcomellas.png","language":"Elixir","readme":"# Constants and Enumerated Values for Elixir\n\nThis module adds support for a `const` macro that exports single constants\nand an `enum` macro that exports enumerated constant values from a module.\nThese values can be used in guards, match expressions or within normal\nexpressions, as the macro takes care of expanding the reference to the\nconstant or enumerated value to its corresponding literal value or function\ncall, depending on the context where it was used.\n\n## Installation\n\nThe package can be installed by adding `ex_const` to your list of dependencies\nin `mix.exs`:\n\n```elixir\ndef deps do\n  [{:ex_const, \"~\u003e 0.3.0\"}]\nend\n```\n\nDocumentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)\nand published on [HexDocs](https://hexdocs.pm). Once published, the docs can\nbe found at [https://hexdocs.pm/ex_const](https://hexdocs.pm/ex_const).\n\n## Usage\n\nA module using `const` or `enum` macros can be defined in the following way:\n\n```elixir\ndefmodule Settings\n  use Const\n  import Bitwise, only: [bsl: 2]\n\n  @ar \"AR\"\n  @it \"IT\"\n  @us \"US\"\n\n  const version, do: \"1.0\"\n\n  const base_path, do: System.cwd()\n\n  const country_codes, do: [@ar, @it, @us]\n\n  enum country_code, do: [argentina: @ar, italy: @it, usa: @us]\n\n  enum color do\n    red   bsl(0xff, 16)\n    green bsl(0xff, 8)\n    blue  bsl(0xff, 0)\n  end\n\n  enum color_tuple do\n    red   {255, 0, 0}\n    green {0, 255, 0}\n    blue  {0, 0, 255}\n  end\nend\n```\n\nAs you can see, the constants can be assigned both literal values or\nexpressions that will be resolved at compile-time.\n\n### Single Constants\n\nYou can create single constant values by using the `const` macro with the\nfollowing syntax:\n\n```elixir\nconst \u003cname\u003e, do: \u003cvalue\u003e\n```\n\ne.g.\n\n```elixir\nconst version, do: \"1.0\"\n```\n\nThe macro invocation will create and export another macro with the name that\nwas set in the `const` declaration (e.g. `version/0`) and replace each\nreference to it with the value that was assigned to it (e.g. `\"1.0\"`).\n\nYou can use any expression that can be resolved at compile-time as the value\nfor the `const`.\n\nThe single constants can be accessed with a nomal function invocation:\n\n```elixir\nrequire Settings\nSettings.version\n```\n\nAs the reference to the `const` will be replaced by its literal value, you\ncan even use them in match expressions or in guards. e.g.\n\n```elixir\nrequire Settings\nSettings.version = \"1.0\"\n```\n\n### Enumerated Values\n\nYou can create enumerated values by using the `enum` macro with the compact\nsyntax:\n\n```elixir\nenum \u003cname\u003e, do: [\u003ckey_1\u003e: \u003cvalue_1\u003e, \u003ckey_2\u003e: \u003cvalue_2\u003e, ...]\n```\n\nOr with the expanded syntax:\n\n```elixir\nenum \u003cname\u003e do\n  \u003ckey_1\u003e \u003cvalue_1\u003e\n  \u003ckey_2\u003e \u003cvalue_2\u003e\n  [...]\nend\n```\n\ne.g.\n\n```elixir\nenum country_code, do: [argentina: \"AR\", italy: \"IT\", usa: \"US\"]\n```\n\nOr:\n\n```elixir\nenum country_code do\n  argentina \"AR\"\n  italy     \"IT\"\n  usa       \"US\"\nend\n```\n\nFor each `enum` instance, the macro will create the following additional macros\nand functions in the module where it was invoked:\n\n  1. Macro with the name that was assigned to the `enum`. This macro will\n     replace every reference to itself with its literal value (if it was called\n     with a literal atom as key or was referenced from a match expression) or\n     with a call to the fallback function.\n  2. Fallback function with a name formed by appending the string `_enum` to\n     the name of the `enum` (e.g. `country_code_enum/1`).\n  3. Function that will retrieve the key corresponding to a value in the\n     `enum`. If there are is more than one key with the same value, the first\n     one in the `enum` will be used and the duplicates will be disregarded.\n\ne.g.\n\n```elixir\ndefmacro country_code(atom) :: String.t\ndef country_code_enum(atom) :: String.t\ndef from_country_code(String.t) :: atom\n```\n\nThe enumerated values can be accessed with a function call:\n\n```elixir\nrequire Settings\nSettings.color(:blue)\n```\n\nAnd can also be used in match expressions or guards:\n\n```elixir\nrequire Settings\nimport Settings\nvalue = \"AR\"\ncase value do\n  country_code(:argentina) -\u003e\n    {:ok, \"Argentina\"}\n  country_code(:italy) -\u003e\n    {:ok, \"Italy\"}\n  code when code == country_code(:usa) -\u003e\n    {:ok, \"United States\"}\n  _ -\u003e\n    {:error, {:must_be_one_of, country_codes()}}\nend\n```\n\nAs the expressions assigned to constants will be resolved at compile-time,\nthe previous function would be equivalent to the following one:\n\n```elixir\nvalue = \"AR\"\ncase value do\n  \"AR\" -\u003e {:ok, \"Argentina\"}\n  \"IT\" -\u003e {:ok, \"Italy\"}\n  code when code == \"US\" -\u003e {:ok, \"United States\"}\n  _ -\u003e {:error, {:must_be_one_of, [\"AR\", \"IT\", \"US\"]}}\nend\n```\n\nSometimes, when an `enum` is referenced in the code, the key to its value is\npassed as an expression that cannot be resolved at compile-time. In those\ncases the expression will be expanded to a function invocation instead of to\na literal value:\n\n```elixir\nrequire Settings\nkey = :green\nSettings.color_tuple(key)\n```\n\nThis works because the macro replaces the reference to itself with a call to\nthe fallback function. The name of the function is that of the `enum`\nwith the `_enum` string appended to it. For example, for an enum named\n`country` the function will be `country_enum/1`. You have to keep this in\nmind when you import the module where the `enum` was defined and restrict\nthe functions that are imported.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjcomellas%2Fex_const","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjcomellas%2Fex_const","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjcomellas%2Fex_const/lists"}