ash_cubdb/lib/ash_cub_db/transformers/configure_directory_transformer.ex
James Harton 74d878b70e
All checks were successful
continuous-integration/drone/push Build is passing
feat: create and read works.
2023-09-29 20:30:42 +13:00

69 lines
1.9 KiB
Elixir

defmodule AshCubDB.ConfigureDirectoryTransformer do
@moduledoc false
alias Spark.{Dsl, Dsl.Transformer, Error.DslError}
use Transformer
@doc false
@impl true
@spec transform(Dsl.t()) :: {:ok, Dsl.t()} | {:error, DslError.t()}
def transform(dsl_state) do
module = Transformer.get_persisted(dsl_state, :module)
with nil <- Transformer.get_option(dsl_state, [:cubdb], :directory),
nil <- Transformer.get_option(dsl_state, [:cubdb], :otp_app),
nil <- Application.get_application(module) do
message = """
Unable to infer a data storage path for this resource.
You can either set the `cubdb.directory` DSL option directly, or set the `cubdb.otp_app` option
to use the application's priv directory for storage.
"""
{:error, DslError.exception(module: module, path: [:cubdb], message: message)}
else
path when is_binary(path) ->
verify_directory(dsl_state, path)
otp_app when is_atom(otp_app) ->
dsl_state =
dsl_state
|> Transformer.set_option([:cubdb], :otp_app, otp_app)
|> Transformer.set_option([:cubdb], :directory, generate_directory(dsl_state))
{:ok, dsl_state}
end
end
defp generate_directory(dsl_state) do
otp_app = Transformer.get_option(dsl_state, [:cubdb], :otp_app)
short_name =
dsl_state
|> Transformer.get_persisted(:module)
|> Module.split()
|> List.last()
|> Macro.underscore()
otp_app
|> :code.priv_dir()
|> Path.join("cubdb")
|> Path.join(short_name)
end
defp verify_directory(dsl_state, path) do
case Path.type(path) do
:absolute ->
{:ok, dsl_state}
_ ->
{:error,
DslError.exception(
module: Transformer.get_persisted(dsl_state, :module),
path: [:cubdb],
message: "Directory must be an absolute path"
)}
end
end
end