Packages
absinthe
0.4.0
1.11.0
1.10.2
1.10.1
1.10.0
1.9.1
1.9.0
1.8.0
1.7.11
1.7.10
1.7.9
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.6.8
1.6.7
retired
1.6.6
1.6.5
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.6.0-rc.1
1.6.0-rc.0
1.5.5
1.5.4
1.5.3
1.5.2
1.5.1
1.5.0
1.5.0-rc.5
1.5.0-rc.4
1.5.0-rc.3
1.5.0-rc.2
1.5.0-rc.1
1.5.0-rc.0
1.5.0-beta.2
1.5.0-beta.1
1.5.0-beta.0
1.5.0-alpha.4
1.5.0-alpha.3
1.5.0-alpha.2
1.5.0-alpha.1
1.5.0-alpha.0
1.4.16
1.4.15
1.4.14
1.4.13
1.4.12
1.4.11
1.4.10
1.4.9
1.4.8
retired
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.4.0-rc.3
1.4.0-rc.2
1.4.0-rc.1
1.4.0-rc.0
1.4.0-beta.5
1.4.0-beta.4
1.4.0-beta.3
1.4.0-beta.2
1.4.0-beta.1
1.3.2
1.3.1
1.3.0
1.3.0-rc.0
1.3.0-beta.2
1.3.0-beta.1
1.3.0-beta.0
1.2.6
1.2.5
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.2.0-rc.0
1.2.0-beta.0
1.2.0-alpha0
1.2.0-alpha.2
1.2.0-alpha.1
1.1.11
1.1.10
1.1.9
1.1.8
1.1.7
1.1.6
1.1.5
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.0.0
0.5.2
0.5.1
0.5.0
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.2.3
0.2.2
0.2.1
0.1.0
GraphQL for Elixir
Current section
Files
Jump to
Current section
Files
lib/absinthe/schema/interface_map.ex
defmodule Absinthe.Schema.InterfaceMap do
# Builds a mapping of interface names to the types that implement them
@moduledoc false
alias Absinthe.Type
alias Absinthe.Schema.TypeMap
alias Absinthe.Schema
@type t :: %{atom => [atom]}
@typep acc_t :: {t, [binary]}
# Discover the mappings of interfaces to types that implement them
@doc false
@spec setup(Schema.t) :: Schema.t
def setup(%{types: types} = schema) do
{mapping, errors} = types
|> Enum.reduce({%{}, []}, fn
{_, %{interfaces: _}} = implementor, acc ->
add_entry(implementor, types, acc)
_, acc ->
acc
end)
%{schema | interfaces: mapping, errors: schema.errors ++ errors}
end
# Add an entry for an implementor (ind it's interfaces, if necessary)
@spec add_entry({atom, Type.t}, TypeMap.t, acc_t) :: acc_t
defp add_entry({identifier, %{interfaces: interfaces} = type_struct}, types, acc) do
interfaces
|> Enum.reduce(acc, fn
iface, {mapping, errors} ->
case types[iface] do
%Type.Interface{} = iface_struct ->
if Type.Interface.implements?(iface_struct, type_struct) do
{
Map.merge(mapping, %{iface => [identifier]}, fn
_, v1, v2 -> v1 ++ v2
end),
errors
}
else
err = "The :#{identifier} object type does not implement the :#{iface} interface type, as declared"
{mapping, [err | errors]}
end
|> check_resolvers(identifier, type_struct, iface, iface_struct)
%{__struct__: struct_type} ->
short_name = struct_type |> Module.split |> List.last
err = "The :#{identifier} object type may only implement Interface types, it cannot implement :#{iface} (#{short_name})"
{mapping, [err | errors]}
end
end)
end
defp check_resolvers({mapping, errors}, identifier, %{is_type_of: nil}, iface, %{resolve_type: nil}) do
err = "Interface type :#{iface} does not provide a `resolve_type` function and implementing type :#{identifier} does not provide an `is_type_of` function. There is no way to resolve this implementing type during execution."
{mapping, [err | errors]}
end
defp check_resolvers(acc, _identifier, _type_struct, _iface, _iface_struct) do
acc
end
end