defmodule Mimi.Store do
@moduledoc """
An `Agent` backend for memoization.
"""
use Agent
@doc """
Start the Agent process and initialize with an empty map.
"""
def start_link(), do: Agent.start_link(fn -> %{} end)
@doc """
Get a value associated with the given `key` or add and return the result of
`fun.()` if the key isn't present.
"""
def get_or_put(pid, key, fun) do
case Agent.get(pid, &Map.fetch(&1, key)) do
{:ok, value} ->
value
:error ->
value = fun.()
Agent.update(pid, &Map.put(&1, key, value))
value
end
end
end