2019-08-30 09:14:01 -07:00
|
|
|
defmodule Pleroma.Docs.Generator do
|
2019-08-30 03:21:48 -07:00
|
|
|
@callback process(keyword()) :: {:ok, String.t()}
|
|
|
|
|
|
|
|
@spec process(module(), keyword()) :: {:ok, String.t()}
|
|
|
|
def process(implementation, descriptions) do
|
|
|
|
implementation.process(descriptions)
|
|
|
|
end
|
|
|
|
|
2019-09-29 01:17:38 -07:00
|
|
|
@spec list_modules_in_dir(String.t(), String.t()) :: [module()]
|
|
|
|
def list_modules_in_dir(dir, start) do
|
|
|
|
with {:ok, files} <- File.ls(dir) do
|
|
|
|
files
|
|
|
|
|> Enum.filter(&String.ends_with?(&1, ".ex"))
|
|
|
|
|> Enum.map(fn filename ->
|
|
|
|
module = filename |> String.trim_trailing(".ex") |> Macro.camelize()
|
2020-02-10 07:28:30 -08:00
|
|
|
String.to_atom(start <> module)
|
2019-09-29 01:17:38 -07:00
|
|
|
end)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
@doc """
|
|
|
|
Converts:
|
|
|
|
- atoms to strings with leading `:`
|
|
|
|
- module names to strings, without leading `Elixir.`
|
|
|
|
- add humanized labels to `keys` if label is not defined, e.g. `:instance` -> `Instance`
|
|
|
|
"""
|
|
|
|
@spec convert_to_strings([map()]) :: [map()]
|
|
|
|
def convert_to_strings(descriptions) do
|
|
|
|
Enum.map(descriptions, &format_entity(&1))
|
|
|
|
end
|
|
|
|
|
|
|
|
defp format_entity(entity) do
|
|
|
|
entity
|
|
|
|
|> format_key()
|
|
|
|
|> Map.put(:group, atom_to_string(entity[:group]))
|
|
|
|
|> format_children()
|
|
|
|
end
|
2019-08-30 03:21:48 -07:00
|
|
|
|
2019-09-29 01:17:38 -07:00
|
|
|
defp format_key(%{key: key} = entity) do
|
|
|
|
entity
|
|
|
|
|> Map.put(:key, atom_to_string(key))
|
|
|
|
|> Map.put(:label, entity[:label] || humanize(key))
|
|
|
|
end
|
2019-08-30 03:21:48 -07:00
|
|
|
|
2019-09-29 01:17:38 -07:00
|
|
|
defp format_key(%{group: group} = entity) do
|
|
|
|
Map.put(entity, :label, entity[:label] || humanize(group))
|
2019-08-30 03:21:48 -07:00
|
|
|
end
|
|
|
|
|
2019-09-29 01:17:38 -07:00
|
|
|
defp format_key(entity), do: entity
|
|
|
|
|
|
|
|
defp format_children(%{children: children} = entity) do
|
|
|
|
Map.put(entity, :children, Enum.map(children, &format_child(&1)))
|
|
|
|
end
|
2019-08-30 03:21:48 -07:00
|
|
|
|
2019-09-29 01:17:38 -07:00
|
|
|
defp format_children(entity), do: entity
|
|
|
|
|
|
|
|
defp format_child(%{suggestions: suggestions} = entity) do
|
|
|
|
entity
|
|
|
|
|> Map.put(:suggestions, format_suggestions(suggestions))
|
|
|
|
|> format_key()
|
2019-12-19 23:22:53 -08:00
|
|
|
|> format_group()
|
2019-09-29 01:17:38 -07:00
|
|
|
|> format_children()
|
|
|
|
end
|
2019-08-30 03:21:48 -07:00
|
|
|
|
2019-09-29 01:17:38 -07:00
|
|
|
defp format_child(entity) do
|
|
|
|
entity
|
|
|
|
|> format_key()
|
2019-12-19 23:22:53 -08:00
|
|
|
|> format_group()
|
2019-09-29 01:17:38 -07:00
|
|
|
|> format_children()
|
2019-08-30 03:21:48 -07:00
|
|
|
end
|
|
|
|
|
2019-12-19 23:22:53 -08:00
|
|
|
defp format_group(%{group: group} = entity) do
|
|
|
|
Map.put(entity, :group, format_suggestion(group))
|
|
|
|
end
|
|
|
|
|
|
|
|
defp format_group(entity), do: entity
|
|
|
|
|
2019-09-29 01:17:38 -07:00
|
|
|
defp atom_to_string(entity) when is_binary(entity), do: entity
|
2019-08-30 03:21:48 -07:00
|
|
|
|
2019-09-29 01:17:38 -07:00
|
|
|
defp atom_to_string(entity) when is_atom(entity), do: inspect(entity)
|
2019-08-30 03:21:48 -07:00
|
|
|
|
2019-09-29 01:17:38 -07:00
|
|
|
defp humanize(entity) do
|
|
|
|
string = inspect(entity)
|
|
|
|
|
|
|
|
if String.starts_with?(string, ":"),
|
|
|
|
do: Phoenix.Naming.humanize(entity),
|
|
|
|
else: string
|
2019-08-30 03:21:48 -07:00
|
|
|
end
|
|
|
|
|
2019-09-29 01:17:38 -07:00
|
|
|
defp format_suggestions([]), do: []
|
|
|
|
|
|
|
|
defp format_suggestions([suggestion | tail]) do
|
|
|
|
[format_suggestion(suggestion) | format_suggestions(tail)]
|
|
|
|
end
|
|
|
|
|
|
|
|
defp format_suggestion(entity) when is_atom(entity) do
|
|
|
|
atom_to_string(entity)
|
|
|
|
end
|
2019-08-30 03:21:48 -07:00
|
|
|
|
2019-09-29 01:17:38 -07:00
|
|
|
defp format_suggestion([head | tail] = entity) when is_list(entity) do
|
|
|
|
[format_suggestion(head) | format_suggestions(tail)]
|
|
|
|
end
|
2019-08-30 03:21:48 -07:00
|
|
|
|
2019-09-29 01:17:38 -07:00
|
|
|
defp format_suggestion(entity) when is_tuple(entity) do
|
|
|
|
format_suggestions(Tuple.to_list(entity)) |> List.to_tuple()
|
2019-08-30 03:21:48 -07:00
|
|
|
end
|
2019-09-29 01:17:38 -07:00
|
|
|
|
|
|
|
defp format_suggestion(entity), do: entity
|
2019-08-30 03:21:48 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
defimpl Jason.Encoder, for: Tuple do
|
2019-09-29 01:17:38 -07:00
|
|
|
def encode(tuple, opts), do: Jason.Encode.list(Tuple.to_list(tuple), opts)
|
2019-08-30 03:21:48 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
defimpl Jason.Encoder, for: [Regex, Function] do
|
2019-09-29 01:17:38 -07:00
|
|
|
def encode(term, opts), do: Jason.Encode.string(inspect(term), opts)
|
2019-08-30 03:21:48 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
defimpl String.Chars, for: Regex do
|
2019-09-29 01:17:38 -07:00
|
|
|
def to_string(term), do: inspect(term)
|
2019-08-30 03:21:48 -07:00
|
|
|
end
|