defmodule ChoiceContext do defstruct [:mode, :choices] use GenServer # API def start_link(timeout, choices) do __MODULE__ |> GenServer.start_link({timeout, choices}, name: __MODULE__) end def start(timeout, choices) do __MODULE__ |> GenServer.start({timeout, choices}, name: __MODULE__) end def accept(server \\ __MODULE__, choice) do server |> GenServer.call({:accept, choice}) end # Callbacks def init({timeout, choices}) do self() |> Process.send_after(:timeout, timeout) {:ok, %__MODULE__{mode: :active, choices: choices}} end def handle_call({:accept, choice}, _from, %__MODULE__{mode: :active, choices: choices} = state) do result = if choice in choices do {:stop, :normal, {:choice, choice}, state} else {:reply, {:reply, "Valid choices are: *#{choices |> Enum.join(~S|, |)}*"}, state} end end def handle_call(_, _from, %__MODULE__{mode: :inactive} = state) do {:stop, :normal, {:reply, "Too late, the choise context has ended."}, state} end def handle_info(:timeout, state) do {:noreply, %{state|mode: :inactive}} end end