Catch-all thread

@dimitarvp Oh, that’s not intended. I have focused on copy-pasting examples of definitions and other features like migration (see first post). Components are a tiny things and everyone is different, so I just don’t wanted to copy-paste all documentation. :smiley:

Generally the library covers many use cases for enum, so the best examples for you depend on what’s your needs.

Ecto.Enum is a simple module that implements Ecto.ParameterizedType behaviour. That’s what one of my components do. My version is more complex and generates a case statement at compile-time, so it should be much more faster.

For example if you pass ecto_type: :id or ecto_type: :integer option then instead of enum id (like :first) it would save the enum index (like 1) into the database. That’s said you don’t have to use ecto at all if you want just Elixir-side features or write a component to integrate enum with other library. :smiling_face_with_sunglasses:

What I wrote before is just direct comparison to Ecto.Enum module. The library offers much more features and covers many other cases (database validations using enumerated type for static values or relation for dynamic values). The main documentation page mentions all use cases and provides a mermaid graph for comparison of features. :books:

What you may find interesting is also a fact that all DSL macros uses Enumex.macro_input(type) type which means that you can pass any Elixir expression including module attributes, variables or function calls. The code works in the module compilation-time and not specific DSL compilation time. :light_bulb:

Yes, as mentioned in this reply I split the documentation on the enum module definitions and components. I could copy-paste example of one component, but you may be interested in using another one, but let’s try …

defmodule MyApp.Enums do
  use Enumex.Static, components: [
    Enumex.Static.Components.Guards,
    Enumex.Static.Components.Typespecs
  ]

  enum :my_enum, ~w[first second third]a
  # you can define other enums in the same module
  # using maps, keywords, mixed list or value DSL
  # and all of them would implement components specified above
end

# generates types like:
@type my_enum_id() :: :first | :second | :third
@type my_enum_index() :: 1 | 2 | 3
@type my_enum_value() ::
  Enumex.Value.t(MyApp.Enums, :my_enum, :first, 1)
  | Enumex.Value.t(MyApp.Enums, :my_enum, :second, 2)
  | Enumex.Value.t(MyApp.Enums, :my_enum, :third, 3)

I decided to share this example as I did not saw anyone working on similar components/features before for enums.

defmodule MyApp.SomeModule do
  alias MyApp.Enums

  require Enums

  @spec sample(Enums.my_enum_id()) :: :ok
  def sample(enum_id) when Enums.is_valid_id(enum_id), do: :ok
end

# vs

defmodule MyApp.SomeModule do
  # Those ids are simple, but imagine you have to document and guard
  # many complex functions, all http status codes, enum value structs and so on …
  @spec sample(:first | :second | :third) :: :ok
  def sample(enum_id) when enum_id in ~w[first second third]a, do: :ok
end

The components give you freedom. You can work on list of ids and fetch index when needed, same for index and same goes for opposite case. You can also simply work on a list of values, but I imagine that in some sensitive cases it’s better to work on as small amount of data as possible (without using maps or structs).


I’m really thankful for those questions. As you see this library is something more than complex version of Ecto.Enum and I need a bit more precise use cases to provide examples you need. Do you need to import absinthe enum definitions or maybe something else? Let me know! :thinking:

I highly recommend to read the documentation starting from introduction, then how to define enum (or simple see examples in the guides instead) and then focus on the component you are interested in. Each one gives you completely different features that you may use alone or together. It’s up to you what features would have your enum module.

Advanced features for databases like migration and adapter could be read later if you find this library helpful for your use case or if you need to work with PostgreSQL enumerated type instead of plain values or when you would like to query index for specific enum id using a custom database function.

2 Likes