enum.ex (3376B)
1 defmodule Absinthe.Type.Enum do 2 @moduledoc """ 3 Used to define an enum type, a special scalar that can only have a defined set 4 of values. 5 6 See the `t` type below for details and examples. 7 8 ## Examples 9 10 Given a type defined as the following (see `Absinthe.Schema.Notation`): 11 12 ``` 13 @desc "The selected color channel" 14 enum :color_channel do 15 value :red, as: :r, description: "Color Red" 16 value :green, as: :g, description: "Color Green" 17 value :blue, as: :b, description: "Color Blue" 18 value :alpha, as: :a, deprecate: "We no longer support opacity settings", description: "Alpha Channel" 19 end 20 ``` 21 22 The "ColorChannel" type (referred inside Absinthe as `:color_channel`) is an 23 Enum type, with values with names "red", "green", "blue", and "alpha" that map 24 to internal, raw values `:r`, `:g`, `:b`, and `:a`. The alpha color channel 25 is deprecated, just as fields and arguments can be. 26 27 You can omit the raw `value` if you'd like it to be the same as the 28 identifier. For instance, in this example the `value` is automatically set to 29 `:red`: 30 31 ``` 32 enum :color_channel do 33 description "The selected color channel" 34 35 value :red, description: "Color Red" 36 value :green, description: "Color Green" 37 value :blue, description: "Color Blue" 38 value :alpha, deprecate: "We no longer support opacity settings", description: "Alpha Channel" 39 end 40 ``` 41 42 If you really want to use a shorthand, skipping support for descriptions, 43 custom raw values, and deprecation, you can just provide a list of atoms: 44 45 ``` 46 enum :color_channel, values: [:red, :green, :blue, :alpha] 47 ``` 48 49 Keep in mind that writing a terse definition that skips descriptions and 50 deprecations today may hamper tooling that relies on introspection tomorrow. 51 52 """ 53 54 use Absinthe.Introspection.TypeKind, :enum 55 56 alias Absinthe.{Blueprint, Type} 57 58 @typedoc """ 59 A defined enum type. 60 61 Should be defined using `Absinthe.Schema.Notation.enum/2`. 62 63 * `:name` - The name of the enum type. Should be a TitleCased `binary`. Set automatically. 64 * `:description` - A nice description for introspection. 65 * `:values` - The enum values, usually provided using the `Absinthe.Schema.Notation.values/1` or `Absinthe.Schema.Notation.value/1` macro. 66 67 68 The `__private__` and `:__reference__` fields are for internal use. 69 """ 70 @type t :: %__MODULE__{ 71 name: binary, 72 description: binary, 73 values: %{binary => Type.Enum.Value.t()}, 74 identifier: atom, 75 __private__: Keyword.t(), 76 definition: module, 77 __reference__: Type.Reference.t() 78 } 79 80 defstruct name: nil, 81 description: nil, 82 identifier: nil, 83 values: %{}, 84 values_by_internal_value: %{}, 85 values_by_name: %{}, 86 __private__: [], 87 definition: nil, 88 __reference__: nil 89 90 # Get the internal representation of an enum value 91 @doc false 92 @spec parse(t, any) :: any 93 def parse(enum, %Blueprint.Input.Enum{value: external_value}) do 94 Map.fetch(enum.values_by_name, external_value) 95 end 96 97 def parse(_, _) do 98 :error 99 end 100 101 # Get the external representation of an enum value 102 @doc false 103 @spec serialize(t, any) :: binary 104 def serialize(enum, internal_value) do 105 Map.fetch!(enum.values_by_internal_value, internal_value).name 106 end 107 end