{"id":15362291,"url":"https://github.com/gyson/ex_type_struct","last_synced_at":"2025-03-27T20:22:16.749Z","repository":{"id":62429479,"uuid":"332399972","full_name":"gyson/ex_type_struct","owner":"gyson","description":"A simple and concise way to annotate structs (or exceptions) with type info.","archived":false,"fork":false,"pushed_at":"2021-01-26T03:59:16.000Z","size":14,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-03T10:04:41.913Z","etag":null,"topics":["elixir","struct","type"],"latest_commit_sha":null,"homepage":"https://hex.pm/packages/ex_type_struct","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gyson.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}},"created_at":"2021-01-24T08:24:53.000Z","updated_at":"2021-02-24T14:04:52.000Z","dependencies_parsed_at":"2022-11-01T20:04:22.987Z","dependency_job_id":null,"html_url":"https://github.com/gyson/ex_type_struct","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gyson%2Fex_type_struct","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gyson%2Fex_type_struct/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gyson%2Fex_type_struct/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gyson%2Fex_type_struct/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gyson","download_url":"https://codeload.github.com/gyson/ex_type_struct/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245917176,"owners_count":20693475,"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":["elixir","struct","type"],"created_at":"2024-10-01T12:59:57.850Z","updated_at":"2025-03-27T20:22:16.722Z","avatar_url":"https://github.com/gyson.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ExTypeStruct\n\nA simple and concise way to annotate structs (or exceptions) with type info.\n\n## Installation\n\nThe package can be installed by adding `ex_type_struct` to your list of dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [\n    {:ex_type_struct, \"~\u003e 0.1\"}\n  ]\nend\n```\n\n## Usage\n\n```elixir\ndefmodule MyStruct do\n  use ExTypeStruct do\n    # this is a required field\n    required_field :: required_field_type()\n\n    # this is an optional field\n    optional_field :: optional_field_type() \\\\ default_value()\n\n    # ^^^ required and optional fields are distinguished by if they have default value.\n  end\nend\n\ndefmodule MyException do\n  use ExTypeStruct.Exception do\n    # this is a required field\n    required_field :: required_field_type()\n\n    # this is an optional field\n    optional_field :: optional_field_type() \\\\ default_value()\n\n    # ^^^ required and optional fields are distinguished by if they have default value.\n  end\nend\n```\n\n- Use `do ... end` block to contain a list of required / optional fields.\n- Required fields must have form `field_name :: field_type`.\n- Required fields would be added to `@enforce_keys` automatically.\n- Optional fields must have form `field_name :: field_type \\\\ default_value`.\n- Optional fields won't be added to `@enforce_keys`.\n\n## Example\n\n### No fields\n\n```elixir\ndefmodule MyStruct do\n  use ExTypeStruct do\n  end\nend\n\n# above code would be compiled / transformed to following code:\n\ndefmodule MyStruct do\n  @enforce_keys []\n\n  defstruct []\n\n  @type t() :: %__MODULE__{}\nend\n```\n\n### Only required fields\n\n```elixir\ndefmodule MyStruct do\n  use ExTypeStruct do\n    name :: String.t()\n    age :: integer()\n  end\nend\n\n# above code would be compiled / transformed to following code:\n\ndefmodule MyStruct do\n  @enforce_keys [:name, :age]\n\n  defstruct [name: nil, age: nil]\n\n  @type t() :: %__MODULE__{\n    name: String.t(),\n    age: integer()\n  }\nend\n```\n\n### Only optional fields\n\n```elixir\ndefmodule MyStruct do\n  use ExTypeStruct do\n    name :: String.t() \\\\ \"Hello\"\n    age :: integer() \\\\ 123\n  end\nend\n\n# above code would be compiled / transformed to following code:\n\ndefmodule MyStruct do\n  @enforce_keys []\n\n  defstruct [name: \"Hello\", age: 123]\n\n  @type t() :: %__MODULE__{\n    name: String.t(),\n    age: integer()\n  }\nend\n```\n\n### Mixed required and optional fields\n\n```elixir\ndefmodule MyStruct do\n  use ExTypeStruct do\n    name :: String.t()\n    age :: integer() \\\\ 123\n  end\nend\n\n# above code would be compiled / transformed to following code:\n\ndefmodule MyStruct do\n  @enforce_keys [:name]\n\n  defstruct [name: nil, age: 123]\n\n  @type t() :: %__MODULE__{\n    name: String.t(),\n    age: integer()\n  }\nend\n```\n\n### Use opaque type\n\nBy putting custom type attribute as first expr in do block, it would override default `@type t()` type attribute.\n\n```elixir\ndefmodule MyStruct do\n  use ExTypeStruct do\n    @opaque t()\n\n    name :: String.t()\n    age :: integer() \\\\ 123\n  end\nend\n\n# above code would be compiled / transformed to following code:\n\ndefmodule MyStruct do\n  @enforce_keys [:name]\n\n  defstruct [name: nil, age: 123]\n\n  @opaque t() :: %__MODULE__{\n    name: String.t(),\n    age: integer()\n  }\nend\n```\n\n### Use a different type name\n\nBy putting custom type attribute as first expr in do block, it would override default `@type t()` type attribute.\n\n```elixir\ndefmodule MyStruct do\n  use ExTypeStruct do\n    @type t_alias()\n\n    name :: String.t()\n    age :: integer() \\\\ 123\n  end\nend\n\n# above code would be compiled / transformed to following code:\n\ndefmodule MyStruct do\n  @enforce_keys [:name]\n\n  defstruct [name: nil, age: 123]\n\n  @type t_alias() :: %__MODULE__{\n    name: String.t(),\n    age: integer()\n  }\nend\n```\n\n### Type with parameters\n\nBy putting custom type attribute as first expr in do block, it would override default `@type t()` type attribute.\n\n```elixir\ndefmodule MyStruct do\n  use ExTypeStruct do\n    @type t(x, y)\n\n    name :: x\n    age :: y \\\\ 123\n  end\nend\n\n# above code would be compiled / transformed to following code:\n\ndefmodule MyStruct do\n  @enforce_keys [:name]\n\n  defstruct [name: nil, age: 123]\n\n  @type t(x, y) :: %__MODULE__{\n    name: x,\n    age: y\n  }\nend\n```\n\n### Support `@typedoc` and `@derive`\n\nNothing special. Just like regular `defstruct` use case.\n\n```elixir\ndefmodule MyStruct do\n\n  @typedoc \"this is type doc\"\n\n  @drive [MyProtocol]\n\n  use ExTypeStruct do\n    name :: String.t()\n    age :: integer() \\\\ 123\n  end\nend\n\n# above code would be compiled / transformed to following code:\n\ndefmodule MyStruct do\n\n  @typedoc \"this is type doc\"\n\n  @drive [MyProtocol]\n\n  @enforce_keys [:name]\n\n  defstruct [name: nil, age: 123]\n\n  @type t() :: %__MODULE__{\n    name: String.t(),\n    age: integer()\n  }\nend\n```\n\n### Support exception\n\n```elixir\ndefmodule MyException do\n  use ExTypeStruct.Exception do\n    message :: String.t()\n  end\nend\n\n# above code would be compiled / transformed to following code:\n\ndefmodule MyException do\n  @enforce_keys [:message]\n\n  defexception [message: nil]\n\n  @type t :: %__MODULE__{\n    message: String.t()\n  }\nend\n```\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgyson%2Fex_type_struct","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgyson%2Fex_type_struct","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgyson%2Fex_type_struct/lists"}