mirror of
https://github.com/ash-project/ash.git
synced 2024-09-19 21:13:10 +12:00
improvement: Expose type t() on Ash.Type.Enum implementations (#1338)
This commit is contained in:
parent
c96a95bcbf
commit
8d3b0b7246
2 changed files with 24 additions and 8 deletions
|
@ -95,25 +95,27 @@ defmodule Ash.Type.Enum do
|
|||
@callback match(term) :: {:ok, atom} | :error
|
||||
|
||||
defmacro __using__(opts) do
|
||||
quote location: :keep, generated: true do
|
||||
quote location: :keep, generated: true, bind_quoted: [opts: opts, behaviour: __MODULE__] do
|
||||
use Ash.Type
|
||||
|
||||
require Ash.Expr
|
||||
|
||||
@behaviour unquote(__MODULE__)
|
||||
@behaviour behaviour
|
||||
|
||||
@values unquote(__MODULE__).build_values(unquote(opts[:values]))
|
||||
@values behaviour.build_values(opts[:values])
|
||||
|
||||
@description_map unquote(__MODULE__).build_description_map(unquote(opts[:values]))
|
||||
@type t() :: unquote(Enum.reduce(@values, &{:|, [], [&1, &2]}))
|
||||
|
||||
@description_map behaviour.build_description_map(opts[:values])
|
||||
|
||||
@string_values @values |> Enum.map(&to_string/1)
|
||||
|
||||
@any_not_downcase? Enum.any?(@string_values, fn value -> String.downcase(value) != value end)
|
||||
|
||||
@impl unquote(__MODULE__)
|
||||
@impl behaviour
|
||||
def values, do: @values
|
||||
|
||||
@impl unquote(__MODULE__)
|
||||
@impl behaviour
|
||||
def description(value) when value in @values, do: Map.get(@description_map, value)
|
||||
|
||||
@impl Ash.Type
|
||||
|
@ -213,7 +215,7 @@ defmodule Ash.Type.Enum do
|
|||
end
|
||||
end
|
||||
|
||||
@impl unquote(__MODULE__)
|
||||
@impl behaviour
|
||||
@spec match?(term) :: boolean
|
||||
def match?(term) do
|
||||
case match(term) do
|
||||
|
@ -222,7 +224,7 @@ defmodule Ash.Type.Enum do
|
|||
end
|
||||
end
|
||||
|
||||
@impl unquote(__MODULE__)
|
||||
@impl behaviour
|
||||
@spec match(term) :: {:ok, atom} | :error
|
||||
def match(value) when value in @values, do: {:ok, value}
|
||||
def match(value) when value in @string_values, do: {:ok, String.to_existing_atom(value)}
|
||||
|
|
|
@ -5,6 +5,7 @@ defmodule Ash.Test.Type.EnumTest do
|
|||
require Ash.Query
|
||||
|
||||
alias Ash.Test.Domain, as: Domain
|
||||
alias Ash.Type.DurationName
|
||||
|
||||
defmodule Status do
|
||||
use Ash.Type.Enum, values: [:open, :Closed, :NeverHappened, :Always_Was]
|
||||
|
@ -103,4 +104,17 @@ defmodule Ash.Test.Type.EnumTest do
|
|||
assert DescriptiveEnum.description(:a_thing_with_no_description) == nil
|
||||
assert DescriptiveEnum.description(:another_thing_with_no_description) == nil
|
||||
end
|
||||
|
||||
test "types are correctly generated" do
|
||||
# Testing with DurationName instead of Status since modules defined in
|
||||
# .exs files are not written to disc and their types therefore can't be
|
||||
# loaded.
|
||||
assert {:ok,
|
||||
[
|
||||
type:
|
||||
{:t,
|
||||
{:type, 0, :union,
|
||||
[{:atom, 0, :microsecond}, _, _, _, _, _, _, _, {:atom, 0, :year}]}, []}
|
||||
]} = Code.Typespec.fetch_types(DurationName)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue