defmodule Patreon.TypeSpecHelpers do
defp create_option_list_ast(struct_ast, keys_to_drop) do
{_, _, struct_atoms} = struct_ast
struct =
Enum.join([:Elixir | struct_atoms], ".")
|> String.to_atom()
|> Kernel.struct()
[last, prev | rest] =
Map.drop(struct, [:__struct__])
|> Map.drop(keys_to_drop)
|> Map.keys()
|> Enum.reverse()
Enum.reduce(rest, {:|, [], [prev, last]}, &{:|, [], [&1, &2]})
end
defmacro struct_to_option_list(_name, struct_ast, keys_to_drop) do
type = create_option_list_ast(struct_ast, keys_to_drop)
quote do
[unquote(type)]
end
end
defmacro struct_to_allowed_option_type(name, struct_ast, keys_to_drop) do
type = create_option_list_ast(struct_ast, keys_to_drop)
quote do
@type unquote(name) :: unquote(type)
end
end
end