1# A tiny proxy that stores all output sent to the group leader
2# while forwarding all requests to it.
3defmodule Phoenix.CodeReloader.Proxy do
4  @moduledoc false
5  use GenServer
6
7  def start() do
8    GenServer.start(__MODULE__, :ok)
9  end
10
11  def stop(proxy) do
12    GenServer.call(proxy, :stop)
13  end
14
15  ## Callbacks
16
17  def init(:ok) do
18    {:ok, ""}
19  end
20
21  def handle_call(:stop, _from, output) do
22    {:stop, :normal, output, output}
23  end
24
25  def handle_info(msg, output) do
26    case msg do
27      {:io_request, from, reply, {:put_chars, chars}} ->
28        put_chars(from, reply, chars, output)
29
30      {:io_request, from, reply, {:put_chars, m, f, as}} ->
31        put_chars(from, reply, apply(m, f, as), output)
32
33      {:io_request, from, reply, {:put_chars, _encoding, chars}} ->
34        put_chars(from, reply, chars, output)
35
36      {:io_request, from, reply, {:put_chars, _encoding, m, f, as}} ->
37        put_chars(from, reply, apply(m, f, as), output)
38
39      {:io_request, _from, _reply, _request} = msg ->
40        send(Process.group_leader, msg)
41        {:noreply, output}
42
43      _ ->
44        {:noreply, output}
45    end
46  end
47
48  defp put_chars(from, reply, chars, output) do
49    send(Process.group_leader, {:io_request, from, reply, {:put_chars, chars}})
50    {:noreply, output <> IO.chardata_to_string(chars)}
51  end
52end
53