Current section

Files

Jump to
absinthe lib absinthe phase document arguments parse.ex
Raw

lib/absinthe/phase/document/arguments/parse.ex

defmodule Absinthe.Phase.Document.Arguments.Parse do
@moduledoc false
# Parses Leaf Node inputs
alias Absinthe.Blueprint.Input
alias Absinthe.{Blueprint, Type}
use Absinthe.Phase
def run(input, options \\ []) do
result = Blueprint.prewalk(input, &handle_node(&1, options[:context] || %{}))
{:ok, result}
end
defp handle_node(%{normalized: nil} = node, _context) do
node
end
defp handle_node(%Input.Value{normalized: normalized} = node, context) do
case build_value(normalized, node.schema_node, context) do
{:ok, value} ->
%{node | data: value}
:not_leaf_node ->
node
{:error, flag} ->
%{node | normalized: normalized |> flag_invalid(flag)}
{:error, flag, reason} ->
normalized = normalized |> flag_invalid(flag, reason)
%{node | normalized: normalized}
end
end
defp handle_node(node, _context), do: node
defp build_value(%Input.Null{}, %Type.NonNull{}, _) do
{:error, :non_null}
end
defp build_value(%{__struct__: struct} = normalized, %Type.Scalar{} = schema_node, context)
when struct in [Input.Boolean, Input.Float, Input.Integer, Input.String, Input.Null] do
case Type.Scalar.parse(schema_node, normalized, context) do
:error ->
{:error, :bad_parse}
{:error, reason} ->
{:error, :bad_parse, reason}
{:ok, val} ->
{:ok, val}
end
end
defp build_value(
%Input.Object{} = normalized,
%Type.Scalar{open_ended: true} = schema_node,
context
) do
case Type.Scalar.parse(schema_node, normalized, context) do
:error ->
{:error, :bad_parse}
{:error, reason} ->
{:error, :bad_parse, reason}
{:ok, val} ->
{:ok, val}
end
end
defp build_value(_normalized, %Type.Scalar{}, _context) do
{:error, :bad_parse}
end
defp build_value(%{value: value} = _normalized, nil = _schema_node, _context) do
{:ok, value}
end
defp build_value(%Input.Null{}, %Type.Enum{}, _) do
{:ok, nil}
end
defp build_value(normalized, %Type.Enum{} = schema_node, _) do
case Type.Enum.parse(schema_node, normalized) do
{:ok, %{value: value}} ->
{:ok, value}
:error ->
{:error, :bad_parse}
end
end
defp build_value(normalized, %Type.NonNull{of_type: inner_type}, context) do
build_value(normalized, inner_type, context)
end
defp build_value(%{__struct__: struct}, %Type.InputObject{}, _)
when struct in [Input.Boolean, Input.Float, Input.Integer, Input.String, Input.Enum] do
{:error, :bad_parse}
end
defp build_value(_, _, _) do
:not_leaf_node
end
end