Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ To `use` `EctoEnum` with string-backed storage:

```elixir
defmodule CustomEnum do
use EctoEnum, "ready", "set", "go"
use EctoEnum, ["ready", "set", "go"]
end
```

Expand Down
13 changes: 0 additions & 13 deletions lib/ecto_enum.ex
Original file line number Diff line number Diff line change
Expand Up @@ -127,19 +127,6 @@ defmodule EctoEnum do
defmacro defenum(module, enum) do
quote do
enum = Macro.escape(unquote(enum))
[h | _t] = enum

enum =
cond do
Keyword.keyword?(enum) ->
enum

is_binary(h) ->
Enum.map(enum, fn value -> {String.to_atom(value), value} end)

true ->
raise "Enum must be a keyword list or a list of strings"
end

defmodule unquote(module) do
use EctoEnum.Use, enum
Expand Down
32 changes: 32 additions & 0 deletions lib/ecto_enum/use.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@ defmodule EctoEnum.Use do

defmacro __using__(opts) do
quote bind_quoted: [opts: opts] do
[h | _t] = opts

opts =
cond do
Keyword.keyword?(opts) ->
opts

is_binary(h) ->
Enum.map(opts, fn value -> {String.to_atom(value), value} end)

true ->
raise "Enum must be a keyword list or a list of strings"
end

typespec = Typespec.make(Keyword.keys(opts))

@behaviour Ecto.Type
Expand Down Expand Up @@ -35,6 +49,12 @@ defmodule EctoEnum.Use do

def cast(_other), do: :error

for {key, value} <- opts, k <- Enum.uniq([key, value, Atom.to_string(key)]) do
def cast!(unquote(k)), do: unquote(key)
end

def cast!(other), do: raise Ecto.CastError, type: __MODULE__, value: other

for {key, value} <- opts, k <- Enum.uniq([key, value, Atom.to_string(key)]) do
def dump(unquote(k)), do: {:ok, unquote(value)}
end
Expand All @@ -47,6 +67,18 @@ defmodule EctoEnum.Use do
raise Ecto.ChangeError, message: msg
end

for {key, value} <- opts, k <- Enum.uniq([key, value, Atom.to_string(key)]) do
def dump!(unquote(k)), do: unquote(value)
end

def dump!(term) do
msg =
"Value `#{inspect(term)}` is not a valid enum for `#{inspect(__MODULE__)}`. " <>
"Valid enums are `#{inspect(__valid_values__())}`"

raise Ecto.ChangeError, message: msg
end

def embed_as(_), do: :self

def equal?(term1, term2), do: term1 == term2
Expand Down