coerce_enums.ex (1199B)
1 defmodule Absinthe.Phase.Document.Arguments.CoerceEnums do 2 @moduledoc false 3 4 # Coerce variable string inputs to enums when appropriate. 5 # 6 # A literal enum like `foo(arg: ENUM)` is parsed as an `Input.Enum` struct. 7 # 8 # However when a variable is used `foo(arg: $enumVar)` the variable input ends up 9 # being an `Input.String` because the variable handler does not yet know the 10 # schema type. This phase coerces string to enum inputs when the schema type 11 # is an Enum. 12 13 use Absinthe.Phase 14 alias Absinthe.{Blueprint, Type} 15 alias Absinthe.Blueprint.Input 16 17 @spec run(Blueprint.t(), Keyword.t()) :: {:ok, Blueprint.t()} 18 def run(input, _options \\ []) do 19 node = Blueprint.prewalk(input, &coerce_node/1) 20 {:ok, node} 21 end 22 23 defp coerce_node(%Input.Value{raw: %{content: %Input.Variable{}}} = node) do 24 node = 25 Blueprint.prewalk(node, fn 26 %Input.String{} = input -> 27 case Type.unwrap(input.schema_node) do 28 %Type.Enum{} -> 29 Map.put(input, :__struct__, Input.Enum) 30 31 _ -> 32 input 33 end 34 35 node -> 36 node 37 end) 38 39 {:halt, node} 40 end 41 42 defp coerce_node(node), do: node 43 end