Enuma
View SourceRust-like Enums for Elixir. Enuma makes it easy to define rich enumeration types similar to Rust, while maintaining Elixir's pattern matching capabilities.
Features
- Define structured enum types with named variants
- No runtime performance overhead due to compile-time evaluation of macros
- Variants can contain no data or structured data
- Pattern matching on enum variants
- Guard-compatible matching with
is_*macros - Optional Ecto integration for database storage
Installation
Add enuma to your list of dependencies in mix.exs:
def deps do
[
{:enuma, "~> 0.1.0"}
]
endUsage
Enuma uses atoms for simple items and tuples for complex items (items with arguments). All Enuma enuma helpers are macros so it will not have any runtime impact on performance.
Basic Usage
defmodule Shape do
use Enuma
defenum do
item :circle, args: [float()] # Circle with radius
item :rectangle, args: [float(), float()] # Rectangle with width and height
item :triangle
end
end
# Creating enum values
circle = Shape.circle(5.0) # {:circle, 5.0}
rect = Shape.rectangle(4.0, 3.0) # {:rectangle, 4.0, 3.0}
triangle = Shape.triangle() # :triangle
# Require is needed to use the Enuma helpers since they are macros
require Shape
def calculate_area(shape) do
case shape do
Shape.circle(r) -> :math.pi() * r * r
Shape.rectangle(w, h) -> w * h
Shape.triangle() -> raise "Area calculation for triangle not implemented"
end
end
# Guard expressions
def print_shape(shape) when Shape.is_circle(shape) do
Shape.circle(radius) = shape
IO.puts("Circle with radius #{radius}")
endEcto Integration
Enuma provides Ecto integration for storing enum values in the database:
defmodule DrawingObject do
use Ecto.Schema
schema "drawing_objects" do
# Using map serialization to support all shape variants including those with parameters
# Using string serialization only works with enums only holding simple types (no arguments)
field :shape, Enuma.Ecto, type: Shape, ecto_type: :map
timestamps()
end
endThe :map serialization format supports all variant types, storing them in the database as JSON-compatible maps:
- Simple variants like
:triangleare stored as%{"key" => "triangle", "values" => []} - Complex variants like
{:circle, 5.0}are stored as%{"key" => "circle", "values" => [5.0]} - Multi-parameter variants like
{:rectangle, 4.0, 3.0}are stored as%{"key" => "rectangle", "values" => [4.0, 3.0]}
Using with changesets:
import Ecto.Changeset
# Valid values include all variants from your enum definition
params = %{
shape: Shape.circle(5.0)
}
# Cast and validate enum values
changeset =
%DrawingObject{}
|> cast(params, [:shape])
|> validate_required([:shape])Read more about Ecto integration in the Enuma.Ecto module documentation.
Documentation
Complete documentation is available at https://hexdocs.pm/enuma.
License
MIT License. See LICENSE file for details.