zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

default_enum_value_present.ex (2524B)


      1 defmodule Absinthe.Phase.Schema.Validation.DefaultEnumValuePresent do
      2   use Absinthe.Phase
      3   alias Absinthe.Blueprint
      4   alias Absinthe.Blueprint.Schema
      5 
      6   def run(blueprint, _opts) do
      7     blueprint = Blueprint.prewalk(blueprint, &validate_schema/1)
      8 
      9     {:ok, blueprint}
     10   end
     11 
     12   def validate_schema(%Schema.SchemaDefinition{} = schema) do
     13     enums =
     14       schema.type_definitions
     15       |> Enum.filter(&match?(%Schema.EnumTypeDefinition{}, &1))
     16       |> Map.new(&{&1.identifier, &1})
     17 
     18     schema = Blueprint.prewalk(schema, &validate_defaults(&1, enums))
     19     {:halt, schema}
     20   end
     21 
     22   def validate_schema(node), do: node
     23 
     24   def validate_defaults(%{default_value: nil} = node, _) do
     25     node
     26   end
     27 
     28   def validate_defaults(%{default_value: default_value, type: type} = node, enums) do
     29     type = Blueprint.TypeReference.unwrap(type)
     30 
     31     case Map.fetch(enums, type) do
     32       {:ok, enum} ->
     33         values = Enum.map(enum.values, & &1.value)
     34         value_list = Enum.map(values, &"\n * #{inspect(&1)}")
     35 
     36         case value_conforms_to_enum(node.type, default_value, values) do
     37           {:error, value} ->
     38             detail = %{
     39               value_list: value_list,
     40               type: type,
     41               default_value: value
     42             }
     43 
     44             node |> put_error(error(node, detail))
     45 
     46           {:ok, _} ->
     47             node
     48         end
     49 
     50       _ ->
     51         node
     52     end
     53   end
     54 
     55   def validate_defaults(node, _) do
     56     node
     57   end
     58 
     59   defp value_conforms_to_enum(%Blueprint.TypeReference.List{of_type: of_type}, value, enum_values)
     60        when is_list(value) do
     61     value
     62     |> Enum.map(&value_conforms_to_enum(of_type, &1, enum_values))
     63     |> Enum.find({:ok, value}, &match?({:error, _}, &1))
     64   end
     65 
     66   defp value_conforms_to_enum(%_{of_type: of_type}, value, enum_values) do
     67     value_conforms_to_enum(of_type, value, enum_values)
     68   end
     69 
     70   defp value_conforms_to_enum(_, value, enum_values) do
     71     if value in enum_values do
     72       {:ok, value}
     73     else
     74       {:error, value}
     75     end
     76   end
     77 
     78   defp error(node, data) do
     79     %Absinthe.Phase.Error{
     80       message: explanation(data),
     81       locations: [node.__reference__.location],
     82       phase: __MODULE__,
     83       extra: data
     84     }
     85   end
     86 
     87   @moduledoc false
     88 
     89   def explanation(%{default_value: default_value, type: type, value_list: value_list}) do
     90     """
     91     The default_value for an enum must be present in the enum values.
     92 
     93     Could not use default value of `#{inspect(default_value)}` for #{inspect(type)}.
     94 
     95     Valid values are:
     96     #{value_list}
     97     """
     98   end
     99 end