defmodule AbsintheGenerator do
@doc "This callback is for each resource to create it's own struct"
@callback run(resource_struct :: struct) :: any
@moduledoc File.read!("./README.md")
@locals_without_parens [
import_types: 1,
import_fields: 1,
arg: 2,
field: 2,
field: 3,
middleware: 1,
middleware: 2,
resolve: 1,
value: 1,
value: 2
]
def moduledoc, do: @moduledoc
def run(%resource_struct{} = struct_data), do: resource_struct.run(struct_data)
def ensure_list_of_structs(list, struct, field_name) do
case Enum.find(list, &(not is_struct(&1, struct))) do
nil -> :ok
non_struct -> raise "The list of #{field_name} must be a list of %#{inspect struct}{} but instead found:\n#{inspect non_struct}"
end
end
def template_path(template_name, ext \\ "ex") do
Path.join(:code.priv_dir(:absinthe_generator), "templates/#{template_name}.#{ext}.eex")
end
def evaluate_template(template_path, assigns) do
template_path
|> EEx.eval_file(assigns)
|> attempt_to_format_template
end
defp attempt_to_format_template(code) do
Code.format_string!(code, locals_without_parens: @locals_without_parens)
rescue
SyntaxError ->
reraise "Error inside the resulting template: \n #{code}", __STACKTRACE__
end
def serialize_struct_to_config(structs) when is_list(structs) do
Enum.map(structs, &serialize_struct_to_config/1)
end
def serialize_struct_to_config(struct) when is_struct(struct) do
struct
|> Map.from_struct
|> serialize_struct_to_config
end
def serialize_struct_to_config(struct) when is_map(struct) do
Enum.reduce(struct, [], fn
({_, nil}, acc) -> acc
({key, value}, acc) when is_struct(value) or is_list(value) ->
Keyword.put(acc, key, serialize_struct_to_config(value))
({key, value}, acc) when is_map(value) ->
Keyword.put(acc, key, serialize_struct_to_config(value))
({key, value}, acc) -> Keyword.put(acc, key, value)
end)
end
def serialize_struct_to_config(value) do
value
end
end