defmodule Box.Source do
@moduledoc """
Utility module to help populate `Box`.
"""
@version "2.1.4"
defstruct [:type, :name, :content, :file_path]
@spec get_icons() :: [%__MODULE__{}]
def get_icons() do
config = Application.get_env(:boxicons_heex, :icons, :all)
get_icons(config)
end
def get_icons(:all) do
config = [regular: :all, solid: :all, logos: :all]
get_icons(config)
end
def get_icons(config) do
validated_config =
Enum.reduce([:regular, :solid, :logos], [], fn type, acc ->
case Keyword.get(config, type) do
nil -> acc
type_config -> [{type, type_config}] ++ acc
end
end)
Enum.reduce(validated_config, [], fn {type, icon_names}, acc ->
get_type_icons(type, icon_names) ++ acc
end)
end
defp get_type_icons(type, icon_names) do
sources =
case icon_names do
nil ->
[]
:all ->
Path.join([File.cwd!(), "lib/downloads/#{@version}/#{type}", "*.svg"])
|> Path.wildcard()
|> Enum.map(fn file_path ->
%__MODULE__{type: type, name: get_name_from_path(file_path), file_path: file_path}
end)
_list ->
icon_names
|> Enum.map(fn icon_name ->
file_path =
Path.join([
File.cwd!(),
"lib/downloads/#{@version}/#{type}",
get_filename(type, icon_name)
])
%__MODULE__{type: type, name: icon_name, file_path: file_path}
end)
end
Enum.map(sources, &populate_source/1)
end
defp populate_source(%__MODULE__{} = source) do
file_content = File.read!(source.file_path)
[_, content] = Regex.run(~r/<svg[^>]*>(.+?)<\/svg>/ms, file_content)
%__MODULE__{source | content: String.trim(content)}
end
defp get_filename(type, icon_name) do
prefix =
case type do
:logos -> "bxl"
:solid -> "bxs"
:regular -> "bx"
end
"#{prefix}-#{icon_name}.svg"
end
defp get_name_from_path(file_path) do
name =
file_path
|> Path.basename()
|> String.split(".")
|> List.first()
|> String.split("-")
|> List.pop_at(0)
|> elem(1)
|> Enum.join("-")
name
end
end