defmodule Payments do
use GenServer
def start_link, do: GenServer.start_link(__MODULE__, nil)
def charges(server), do: GenServer.call(server, :charges)
@impl true
def init(nil), do: {:ok, %{charges: [], seen: %{}}}
@impl true
def handle_call({:charge, nil, amount}, _from, state) do
{:reply, {:ok, :charged}, %{state | charges: state.charges ++ [amount]}}
end
def handle_call({:charge, key, amount}, _from, state) do
case state.seen do
%{^key => result} ->
{:reply, result, state}
_ ->
result = {:ok, {:charged, key}}
state = %{
state
| charges: state.charges ++ [amount],
seen: Map.put(state.seen, key, result)
}
{:reply, result, state}
end
end
def handle_call(:charges, _from, state), do: {:reply, state.charges, state}
end