From 2c19ea1974d60203a47c438c328b810562eac9c1 Mon Sep 17 00:00:00 2001 From: Manuel Rubio Date: Thu, 2 Jul 2020 01:59:21 +0200 Subject: [PATCH 1/3] bugfix string enum and implement cast!/1 --- lib/ecto_enum.ex | 13 ------------- lib/ecto_enum/use.ex | 20 ++++++++++++++++++++ 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/lib/ecto_enum.ex b/lib/ecto_enum.ex index d0d784a..9e375f5 100644 --- a/lib/ecto_enum.ex +++ b/lib/ecto_enum.ex @@ -105,19 +105,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 diff --git a/lib/ecto_enum/use.ex b/lib/ecto_enum/use.ex index 292da2a..783fb91 100644 --- a/lib/ecto_enum/use.ex +++ b/lib/ecto_enum/use.ex @@ -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 @@ -32,6 +46,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 From ce785f01c5b12d8746d885cdbb9a0b39479689f9 Mon Sep 17 00:00:00 2001 From: Manuel Rubio Date: Thu, 2 Jul 2020 02:38:41 +0200 Subject: [PATCH 2/3] implement dump!/1 --- lib/ecto_enum/use.ex | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/ecto_enum/use.ex b/lib/ecto_enum/use.ex index 783fb91..96a9477 100644 --- a/lib/ecto_enum/use.ex +++ b/lib/ecto_enum/use.ex @@ -64,6 +64,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 From add06bb6115d6055af3b6a3e905d8ceb6b5ea2ad Mon Sep 17 00:00:00 2001 From: Manuel Rubio Date: Thu, 2 Jul 2020 16:57:28 +0200 Subject: [PATCH 3/3] fix doc --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b68b670..8b653c8 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,7 @@ To `use` `EctoEnum` with string-backed storage: ```elixir defmodule CustomEnum do - use EctoEnum, "ready", "set", "go" + use EctoEnum, ["ready", "set", "go"] end ```