zf

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

union.ex (3182B)


      1 defmodule Absinthe.Type.Union do
      2   @moduledoc """
      3   A unions is an abstract type made up of multiple possible concrete types.
      4 
      5   No common fields are declared in a union. Compare to `Absinthe.Type.Interface`.
      6 
      7   Because it's necessary for the union to determine the concrete type of a
      8   resolved object, you must either:
      9 
     10   * Provide a `:resolve_type` function on the union
     11   * Provide a `:is_type_of` function on each possible concrete type
     12 
     13   ```
     14   union :search_result do
     15     description "A search result"
     16 
     17     types [:person, :business]
     18     resolve_type fn
     19       %Person{}, _ -> :person
     20       %Business{}, _ -> :business
     21     end
     22   end
     23   ```
     24   """
     25 
     26   use Absinthe.Introspection.TypeKind, :union
     27 
     28   alias Absinthe.{Schema, Type}
     29 
     30   @typedoc """
     31   * `:name` - The name of the union type. Should be a TitleCased `binary`. Set automatically.
     32   * `:description` - A nice description for introspection.
     33   * `:types` - The list of possible types.
     34   * `:resolve_type` - A function used to determine the concrete type of a resolved object. See also `Absinthe.Type.Object`'s `:is_type_of`. Either `resolve_type` is specified in the union type, or every object type in the union must specify `is_type_of`
     35 
     36   The `:resolve_type` function will be passed two arguments; the object whose type needs to be identified, and the `Absinthe.Execution` struct providing the full execution context.
     37 
     38   The `__private__` and `:__reference__` keys are for internal use.
     39 
     40   """
     41   @type t :: %__MODULE__{
     42           name: binary,
     43           description: binary,
     44           types: [Type.identifier_t()],
     45           identifier: atom,
     46           fields: map,
     47           __private__: Keyword.t(),
     48           definition: module,
     49           __reference__: Type.Reference.t()
     50         }
     51 
     52   defstruct name: nil,
     53             description: nil,
     54             identifier: nil,
     55             resolve_type: nil,
     56             types: [],
     57             fields: nil,
     58             __private__: [],
     59             definition: nil,
     60             __reference__: nil
     61 
     62   @doc false
     63   defdelegate functions, to: Absinthe.Blueprint.Schema.UnionTypeDefinition
     64 
     65   @doc false
     66   @spec member?(t, Type.t()) :: boolean
     67   def member?(%{types: types}, %{identifier: ident}) do
     68     ident in types
     69   end
     70 
     71   def member?(_, _) do
     72     false
     73   end
     74 
     75   @doc false
     76   @spec resolve_type(t, any, Absinthe.Resolution.t()) :: Type.t() | nil
     77   def resolve_type(type, object, env, opts \\ [lookup: true])
     78 
     79   def resolve_type(%{types: types} = union, obj, %{schema: schema} = env, opts) do
     80     if resolver = Type.function(union, :resolve_type) do
     81       case resolver.(obj, env) do
     82         nil ->
     83           nil
     84 
     85         ident when is_atom(ident) ->
     86           if opts[:lookup] do
     87             Absinthe.Schema.lookup_type(schema, ident)
     88           else
     89             ident
     90           end
     91       end
     92     else
     93       type_name =
     94         Enum.find(types, fn
     95           %{is_type_of: nil} ->
     96             false
     97 
     98           type ->
     99             type = Absinthe.Schema.lookup_type(schema, type)
    100             Absinthe.Type.function(type, :is_type_of).(obj)
    101         end)
    102 
    103       if opts[:lookup] do
    104         Schema.lookup_type(schema, type_name)
    105       else
    106         type_name
    107       end
    108     end
    109   end
    110 end