Current section
Files
Jump to
Current section
Files
lib/tempel/persistence.ex
defmodule Tempel.Persistence do
@spec init(map()) :: map()
def init(opts), do: opts
@spec save(opts :: map, list(Tempel.Gate.raw_variant()) | Tempel.Gate.raw_variant()) ::
{:error, reason :: any} | {:ok, Tempel.Gate.saved_variant()}
def save(opts, files_variants) when is_list(files_variants) do
result =
Enum.reduce_while(files_variants, [], fn variants, acc ->
case save(opts, variants) do
{:ok, variant_keys} -> {:cont, acc ++ [variant_keys]}
{:error, reason} -> {:halt, {:error, reason}}
end
end)
case result do
{:error, reason} ->
delete(opts, extract_variant_data(files_variants))
{:error, reason}
object_keys ->
{:ok, object_keys}
end
end
def save(opts, variants) do
service = Map.get(opts, :service)
setting = service.init(opts)
result =
Enum.reduce_while(variants, %{}, fn {name, file}, acc ->
case service.save(file, setting) do
{:ok, filename} -> {:cont, Map.put(acc, name, filename)}
{:error, reason} -> {:halt, {:error, reason}}
end
end)
case result do
{:error, reason} ->
files = Enum.map(variants, fn {_key, value} -> get_atom_or_string(value, :filename) end)
delete(opts, files)
{:error, reason}
variant_details ->
{:ok, variant_details}
end
end
@spec delete(
opts :: map,
files ::
list(Tempel.Gate.saved_variant()) | list(String.t()) | Tempel.Gate.saved_variant()
) :: :ok | {:error, reason :: any}
def delete(opts, [variant | _tail] = files_variants) when is_map(variant) do
files =
Enum.reduce(files_variants, [], fn item, acc ->
acc ++ Enum.map(item, fn {_k, v} -> v end)
end)
delete(opts, files)
end
def delete(opts, file_variants) when is_map(file_variants) do
files = Enum.map(file_variants, fn {_k, v} -> v end)
delete(opts, files)
end
def delete(opts, files) do
service = Map.get(opts, :service)
setting = Kernel.apply(service, :init, [opts])
Kernel.apply(service, :delete, [setting, files])
end
@spec to_url(
opts :: map,
files ::
list(Tempel.Gate.saved_variant()) | list(String.t()) | Tempel.Gate.saved_variant()
) ::
list(String.t())
| %{(name :: String.t() | atom()) => url :: String.t()}
| list(%{(name :: String.t() | atom()) => url :: String.t()})
def to_url(opts, [variant | _tail] = files_vairants) when is_map(variant) do
Enum.map(files_vairants, fn file_variants ->
to_url(opts, file_variants)
end)
end
def to_url(opts, file_variants) when is_map(file_variants) do
Enum.reduce(file_variants, %{}, fn {name, path}, acc ->
Map.put(acc, name, to_url(opts, path))
end)
end
def to_url(opts, object_keys) when is_list(object_keys) do
Enum.map(object_keys, &to_url(opts, &1))
end
def to_url(opts, object_key) do
service = Map.get(opts, :service)
setting = Kernel.apply(service, :init, [opts])
Kernel.apply(service, :to_url, [setting, object_key])
end
defp extract_variant_data(files_variants, attr \\ :filename) do
Enum.reduce(files_variants, [], fn variant, acc ->
Enum.map(variant, fn {_key, value} ->
acc ++ [get_atom_or_string(value, attr)]
end)
end)
end
defp get_atom_or_string(map, key) do
Map.get(map, key) || Map.get(map, Atom.to_string(key))
end
end