From 564d095f2a2887c9af71f5762cc0f8e084c7f3dd Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sat, 27 Jun 2020 14:24:54 -0400 Subject: [PATCH] feat: section option configuration --- lib/ash/data_layer/ets/ets.ex | 2 +- lib/ash/dsl/extension.ex | 48 ++++++++++++++++++++++++++++++++--- lib/ash/dsl/section.ex | 11 +++++++- 3 files changed, 56 insertions(+), 5 deletions(-) diff --git a/lib/ash/data_layer/ets/ets.ex b/lib/ash/data_layer/ets/ets.ex index 35e453c67..27a57231d 100644 --- a/lib/ash/data_layer/ets/ets.ex +++ b/lib/ash/data_layer/ets/ets.ex @@ -28,7 +28,7 @@ defmodule Ash.DataLayer.Ets do @spec private?(Ash.resource()) :: boolean def private?(resource) do - Extension.get_opt(resource, [:ets], :private?) || false + Extension.get_opt(resource, [:ets], :private?, false, true) end defmodule Query do diff --git a/lib/ash/dsl/extension.ex b/lib/ash/dsl/extension.ex index 131144bd4..9f55c3531 100644 --- a/lib/ash/dsl/extension.ex +++ b/lib/ash/dsl/extension.ex @@ -106,9 +106,51 @@ defmodule Ash.Dsl.Extension do :persistent_term.get({resource, :ash, path}, %{entities: []}).entities end - @doc "Get an option value for a section at a given path" - def get_opt(resource, path, value) do - :persistent_term.get({resource, :ash, path}, %{opts: []}).opts[value] + @doc """ + Get an option value for a section at a given path. + + Checks to see if it has been overridden via configuration. + """ + def get_opt(resource, path, value, default, configurable? \\ false) do + if configurable? do + case get_opt_config(resource, path, value) do + {:ok, value} -> + value + + _ -> + Keyword.get( + :persistent_term.get({resource, :ash, path}, %{opts: []}).opts, + value, + default + ) + end + else + Keyword.get( + :persistent_term.get({resource, :ash, path}, %{opts: []}).opts, + value, + default + ) + end + end + + def get_opt_config(resource, path, value) do + with {:ok, config} <- Application.fetch_env(:ash, resource), + {:ok, value} <- + path + |> List.wrap() + |> Kernel.++([value]) + |> Enum.reduce_while({:ok, config}, fn key, {:ok, config} -> + if Keyword.keyword?(config) do + case Keyword.fetch(config, key) do + {:ok, value} -> {:cont, {:ok, value}} + :error -> {:halt, :error} + end + else + {:halt, :error} + end + end) do + {:ok, value} + end end @doc false diff --git a/lib/ash/dsl/section.ex b/lib/ash/dsl/section.ex index a72da45bf..1b7aa482b 100644 --- a/lib/ash/dsl/section.ex +++ b/lib/ash/dsl/section.ex @@ -20,13 +20,22 @@ defmodule Ash.Dsl.Section do For a full example, see `Ash.Dsl.Extension`. """ - defstruct [:name, imports: [], schema: [], describe: "", entities: [], sections: []] + defstruct [ + :name, + imports: [], + schema: [], + configurable: [], + describe: "", + entities: [], + sections: [] + ] @type t :: %__MODULE__{ name: atom, describe: String.t(), entities: [Ash.Dsl.Entity.t()], sections: [%__MODULE__{}], + configurable: [atom], schema: NimbleOptions.schema() }