Packages

fnord

0.8.85

AI code archaeology

Current section

Files

Jump to
fnord lib services approvals.ex
Raw

lib/services/approvals.ex

defmodule Services.Approvals do
use GenServer
# ----------------------------------------------------------------------------
# Types
# ----------------------------------------------------------------------------
defstruct [:session]
@type t :: %__MODULE__{
session: [any]
}
# ----------------------------------------------------------------------------
# Globals
# ----------------------------------------------------------------------------
@default_impl %{
edit: Services.Approvals.Edit,
shell: Services.Approvals.Shell
}
# ----------------------------------------------------------------------------
# Client API
# ----------------------------------------------------------------------------
def start_link(opts \\ []) do
name = Keyword.get(opts, :name, __MODULE__)
GenServer.start_link(__MODULE__, nil, name: name)
end
@spec confirm(term, atom) ::
{:ok, :approved}
| {:denied, binary}
| {:error, binary}
def confirm(args, kind) do
GenServer.call(__MODULE__, {:confirm, kind, args}, :infinity)
end
# ----------------------------------------------------------------------------
# Server API
# ----------------------------------------------------------------------------
@impl GenServer
def init(_) do
{:ok, %__MODULE__{session: []}}
end
@impl GenServer
def handle_call({:confirm, kind, args}, _from, state) do
impl = impl_for(kind)
# Execute the confirmation in a UI.Queue context to avoid deadlocks
result =
UI.Queue.run_from_genserver(fn ->
impl.confirm(state, args)
end)
case result do
{:approved, new_state} -> {:reply, {:ok, :approved}, new_state}
{:denied, reason, new_state} -> {:reply, {:denied, reason}, new_state}
{:error, reason, new_state} -> {:reply, {:error, reason}, new_state}
end
end
# ----------------------------------------------------------------------------
# Internals
# ----------------------------------------------------------------------------
defp impl_for(kind) do
Services.Globals.get_env(:fnord, :approvals, @default_impl)
|> Map.fetch!(kind)
end
end