Packages
absinthe
1.2.0-rc.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/notation/scope.ex
defmodule Absinthe.Schema.Notation.Scope do
@moduledoc false
@stack :absinthe_notation_scopes
defstruct name: nil, recordings: [], attrs: []
use Absinthe.Type.Fetch
def open(name, mod, attrs \\ []) do
Module.put_attribute(mod, @stack, [%__MODULE__{name: name, attrs: attrs} | on(mod)])
end
def close(mod) do
{current, rest} = split(mod)
Module.put_attribute(mod, @stack, rest)
current
end
def split(mod) do
case on(mod) do
[] ->
{nil, []}
[current | rest] ->
{current, rest}
end
end
def current(mod) do
{c, _} = split(mod)
c
end
def recorded!(mod, kind, identifier) do
update_current(mod, fn
%{recordings: recs} = scope ->
%{scope | recordings: [{kind, identifier} | recs]}
nil ->
# Outside any scopes, ignore
nil
end)
end
@doc """
Check if a certain operation has been recorded in the current scope.
## Examples
See if an input object with the identifier `:input` has been defined from
this scope:
```
recorded?(mod, :input_object, :input)
```
See if the `:description` attribute has been
```
recorded?(mod, :attr, :description)
```
"""
@spec recorded?(atom, atom, atom) :: boolean
def recorded?(mod, kind, identifier) do
scope = current(mod)
case kind do
:attr ->
# Supports attributes passed directly to the macro that
# created the scope, usually (?) short-circuits the need to
# check the scope recordings.
scope.attrs[identifier] || recording_marked?(scope, kind, identifier)
_ ->
recording_marked?(scope, kind, identifier)
end
end
# Check the list of recordings for `recorded?/3`
defp recording_marked?(scope, kind, identifier) do
scope.recordings
|> Enum.find(fn
{^kind, ^identifier} ->
true
_ ->
false
end)
end
def put_attribute(mod, key, value, opts \\ [accumulate: false]) do
if opts[:accumulate] do
update_current(mod, fn
scope ->
new_attrs = update_in(scope.attrs, [key], &[value | (&1 || [])])
%{scope | attrs: new_attrs}
end)
else
update_current(mod, fn
scope ->
%{scope | attrs: Keyword.put(scope.attrs, key, value)}
end)
end
end
defp update_current(mod, fun) do
{current, rest} = split(mod)
updated = fun.(current)
Module.put_attribute(mod, @stack, [updated | rest])
end
def on(mod) do
case Module.get_attribute(mod, @stack) do
nil ->
Module.put_attribute(mod, @stack, [])
[]
value ->
value
end
end
end