71 lines
2.0 KiB
Elixir
71 lines
2.0 KiB
Elixir
defmodule Translator.Parser do
|
|
@type filename :: String.t()
|
|
@type extension :: String.t()
|
|
@type data :: map
|
|
@type parser :: atom
|
|
@type availiable_parsers_map :: %{required(extension) => parser}
|
|
|
|
@spec load(filename) :: {:error, any} | {:ok, any}
|
|
def load(filename) do
|
|
case select_parser(filename) do
|
|
{:error, message} -> {:error, message}
|
|
{:ok, parser} -> load(filename, parser)
|
|
end
|
|
end
|
|
|
|
@spec load(filename, parser) :: {:error, any} | {:ok, any}
|
|
def load(filename, parser) do
|
|
with {:ok, contents} <- File.read(filename),
|
|
{:ok, result} <- parser.parse(contents) do
|
|
{:ok, result}
|
|
else
|
|
{:error, error} -> {:error, error}
|
|
end
|
|
end
|
|
|
|
@spec save(filename, data) :: {:error, any} | {:ok, any}
|
|
def save(filename, data) do
|
|
case select_parser(filename) do
|
|
{:error, message} -> {:error, message}
|
|
{:ok, parser} -> save(filename, data, parser)
|
|
end
|
|
end
|
|
|
|
@spec save(filename, data, parser) :: :ok | {:error, any}
|
|
def save(filename, data, parser) do
|
|
with {:ok, contents} <- parser.generate(data),
|
|
:ok <- File.write(filename, contents) do
|
|
:ok
|
|
else
|
|
{:error, error} -> {:error, error}
|
|
end
|
|
end
|
|
|
|
@spec select_parser(filename) :: {:ok, atom} | {:error, any}
|
|
defp select_parser(filename) do
|
|
case select_parser!(filename) do
|
|
nil -> {:error, "Couldn't find availiable parser for this extension"}
|
|
value -> {:ok, value}
|
|
end
|
|
end
|
|
|
|
@spec select_parser!(filename) :: atom
|
|
defp select_parser!(filename),
|
|
do: Map.get(availiable(), String.trim_leading(Path.extname(filename), "."))
|
|
|
|
@spec availiable() :: availiable_parsers_map
|
|
defp availiable() do
|
|
Application.get_env(:translator, :parsers)
|
|
|> Enum.reduce(%{}, fn parser, avaliable_extensions_map ->
|
|
{:ok, extensions} = parser.extensions()
|
|
|
|
parser_extensions_map =
|
|
extensions
|
|
|> Enum.map(&{&1, parser})
|
|
|> Map.new()
|
|
|
|
Map.merge(avaliable_extensions_map, parser_extensions_map)
|
|
end)
|
|
end
|
|
end
|