Current section

Files

Jump to
clean_mixer lib clean_mixer arch_map component.ex
Raw

lib/clean_mixer/arch_map/component.ex

defmodule CleanMixer.ArchMap.Component do
alias CleanMixer.CodeMap.SourceFile
alias CleanMixer.CodeMap.FileDependency
alias CleanMixer.CodeMap.CodeModule
@type name :: String.t() | atom
defstruct [
:name,
:files,
:file_dependencies,
meta: %{}
]
@type t :: %__MODULE__{
name: name,
files: list(SourceFile.t()),
file_dependencies: list(FileDependency.t()),
meta: map
}
@subcomponent_delimiter "/"
@spec new(name, list(SourceFile.t()), list(FileDependency.t())) :: t
def new(name, files \\ [], file_dependencies \\ [], meta \\ %{}) do
%__MODULE__{
name: name,
files: files,
file_dependencies: file_dependencies,
meta: meta
}
end
@spec file_dependencies(t, t) :: list(FileDependency.t())
def file_dependencies(component, other_component) do
component.file_dependencies
|> Enum.filter(&(&1.target in other_component.files))
end
@spec child?(t, t) :: boolean
def child?(child_component, parent_component) do
child_component.name
|> to_string()
|> String.starts_with?([parent_component.name, @subcomponent_delimiter] |> Enum.join())
end
@spec has_file?(t, Path.t()) :: boolean
def has_file?(component, path) do
path in Enum.map(component.files, & &1.path)
end
@spec depth(t) :: pos_integer
def depth(%__MODULE__{name: name}) do
name
|> to_string()
|> trim(@subcomponent_delimiter)
|> count_occurences(@subcomponent_delimiter)
end
@spec modules(t) :: list(CodeModule.t())
def modules(%__MODULE__{files: files}) do
Enum.flat_map(files, & &1.modules)
end
defp count_occurences(string, symbol) do
subparts_count =
string
|> String.split(symbol, trim: true)
|> Enum.count()
subparts_count - 1
end
defp trim(string, symbol) do
string
|> String.trim_leading(symbol)
|> String.trim_trailing(symbol)
end
end