Packages

plymio_codi: Generating Quoted Forms for Common Code Patterns

Current section

Files

Jump to
plymio_codi lib codi pattern doc.ex
Raw

lib/codi/pattern/doc.ex

defmodule Plymio.Codi.Pattern.Doc do
@moduledoc false
alias Plymio.Codi, as: CODI
use Plymio.Fontais.Attribute
use Plymio.Codi.Attribute
import Plymio.Codi.Error,
only: [
new_error_result: 1
]
import Plymio.Fontais.Guard,
only: [
is_value_unset_or_nil: 1
]
import Plymio.Codi.Error,
only: [
new_error_result: 1
]
import Plymio.Fontais.Option,
only: [
opts_create_aliases_dict: 1,
# opts_maybe_canonical_keys: 2,
opts_take_canonical_keys: 2
]
import Plymio.Codi.Utility,
only: [
cpo_resolve_fun_module: 1,
cpo_resolve_fun_name: 1,
cpo_resolve_fun_arity: 1
]
import Plymio.Codi.Utility.GetSet
@pattern_doc_kvs_alias [
@plymio_codi_key_alias_pattern,
@plymio_codi_key_alias_status,
@plymio_codi_key_alias_form,
@plymio_codi_key_alias_fun_doc,
@plymio_codi_key_alias_fun_module,
@plymio_codi_key_alias_fun_name,
@plymio_codi_key_alias_fun_args,
@plymio_codi_key_alias_fun_arity,
@plymio_codi_key_alias_delegate_name
]
@pattern_doc_dict_alias @pattern_doc_kvs_alias
|> opts_create_aliases_dict
def cpo_pattern_doc_normalise(opts, dict \\ nil) do
opts |> opts_take_canonical_keys(dict || @pattern_doc_dict_alias)
end
def opts_dict_canonical_keys() do
@pattern_doc_dict_alias
end
defp express_doc_pattern(codi, pattern, opts)
defp express_doc_pattern(%CODI{} = state, pattern, _opts)
when is_value_unset_or_nil(pattern) do
{:ok, {@plymio_fontais_the_unset_value, state}}
end
defp express_doc_pattern(%CODI{} = state, pattern, _opts)
when is_binary(pattern) do
{:ok, {quote(do: @doc(unquote(pattern))), state}}
end
defp express_doc_pattern(%CODI{} = state, pattern, _opts)
when pattern == false do
{:ok, {quote(do: @doc(false)), state}}
end
defp express_doc_pattern(%CODI{} = state, pattern, opts)
when pattern == @plymio_codi_doc_type_bang do
with {:ok, fun_name} <- opts |> cpo_resolve_fun_name,
{:ok, fun_module} <- opts |> cpo_resolve_fun_module,
{:ok, fun_arity} <- opts |> cpo_resolve_fun_arity do
docstring =
fun_module
|> case do
x when is_value_unset_or_nil(x) ->
"Bang function for `#{to_string(fun_name)}/#{fun_arity}`"
x ->
"Bang function for `#{inspect(x)}.#{to_string(fun_name)}/#{fun_arity}`"
end
form =
quote do
@doc unquote(docstring)
end
{:ok, {form, state}}
else
{:error, %{__exception__: true}} = result -> result
end
end
defp express_doc_pattern(%CODI{} = state, pattern, opts)
when pattern == @plymio_codi_doc_type_delegate do
with {:ok, fun_module} <- opts |> cpo_resolve_fun_module,
{:ok, fun_name} <- opts |> cpo_resolve_fun_name,
{:ok, fun_arity} <- opts |> cpo_resolve_fun_arity do
docstring =
fun_module
|> case do
x when is_value_unset_or_nil(x) ->
"Delegated to `#{fun_name}/#{fun_arity}`"
x ->
"Delegated to `#{inspect(x)}.#{fun_name}/#{fun_arity}`"
end
form =
quote do
@doc unquote(docstring)
end
{:ok, {form, state}}
else
{:error, %{__exception__: true}} = result -> result
end
end
defp express_doc_pattern(%CODI{} = state, pattern, opts)
when is_function(pattern, 2) do
pattern.(state, opts)
|> case do
{:error, %{__exception__: true}} = result -> result
{:ok, _} = result -> result
value -> {:ok, value}
end
|> case do
{:error, %{__exception__: true}} = result ->
result
{:ok, value} ->
value
|> case do
x when is_binary(x) -> {:ok, x}
x -> {:ok, x |> inspect}
end
end
end
defp express_doc_pattern(_codi, pattern, opts) do
new_error_result(m: "doc pattern #{inspect(pattern)} invalid", v: opts)
end
def express_pattern(codi, pattern, opts \\ [])
def express_pattern(%CODI{} = state, pattern, cpo)
when pattern == @plymio_codi_pattern_doc do
with {:ok, cpo} <- cpo |> cpo_pattern_doc_normalise,
{:ok, fun_doc} <- cpo |> cpo_get_fun_doc,
{:ok, {form, %CODI{} = state}} <- state |> express_doc_pattern(fun_doc, cpo) do
with {:ok, cpo} <- cpo |> cpo_done_with_form(form) do
{:ok, {cpo, state}}
else
{:error, %{__exception__: true}} = result -> result
end
else
{:error, %{__exception__: true}} = result -> result
end
end
end