Current section

Files

Jump to
iris lib ex_doc group_matcher.ex
Raw

lib/ex_doc/group_matcher.ex

defmodule Iris.ExDoc.GroupMatcher do
# General helpers for dealing with grouping functionality.
# Extracted for organization and testability.
@moduledoc false
@type pattern :: Regex.t() | module() | String.t()
@type patterns :: pattern | [pattern]
@type group_patterns :: keyword(patterns)
@doc """
Finds the index of a given group.
"""
def index(groups, group) do
Enum.find_index(groups, fn {k, _v} -> k == group end) || -1
end
@doc """
Group the following entries and while preserving the order in `groups`.
"""
def group_by(groups, entries, by) do
entries = Enum.group_by(entries, by)
{groups, leftovers} =
Enum.flat_map_reduce(groups, entries, fn group, grouped_nodes ->
case Map.pop(grouped_nodes, group, []) do
{[], grouped_nodes} -> {[], grouped_nodes}
{entries, grouped_nodes} -> {[{group, entries}], grouped_nodes}
end
end)
groups ++ Enum.sort(leftovers)
end
@doc """
Finds a matching group for the given module name, id, and metadata.
"""
def match_module(group_patterns, module, id, metadata) do
match_group_patterns(group_patterns, fn pattern ->
case pattern do
%Regex{} = regex -> Regex.match?(regex, id)
string when is_binary(string) -> id == string
atom when is_atom(atom) -> atom == module
function when is_function(function) -> function.(metadata)
end
end)
end
@doc """
Finds a matching group for the given extra filename
"""
def match_extra(group_patterns, filename) do
match_group_patterns(group_patterns, fn pattern ->
case pattern do
%Regex{} = regex -> Regex.match?(regex, filename)
string when is_binary(string) -> filename == string
end
end)
end
defp match_group_patterns(group_patterns, matcher) do
Enum.find_value(group_patterns, fn {group, patterns} ->
patterns = List.wrap(patterns)
Enum.any?(patterns, matcher) && group
end)
end
end