Packages
io_ansi_table
1.0.4
1.0.40
1.0.39
1.0.38
1.0.37
1.0.36
1.0.34
1.0.33
1.0.32
1.0.31
1.0.30
1.0.29
1.0.28
1.0.27
1.0.26
1.0.25
1.0.24
1.0.23
1.0.22
1.0.21
1.0.20
1.0.19
1.0.18
1.0.17
1.0.16
1.0.15
1.0.14
1.0.13
1.0.12
1.0.11
1.0.10
1.0.9
1.0.8
1.0.7
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
0.4.32
0.4.31
0.4.30
0.4.29
0.4.28
0.4.27
0.4.26
0.4.25
0.4.24
0.4.23
0.4.22
0.4.21
0.4.20
0.4.19
0.4.18
0.4.17
0.4.16
0.4.15
0.4.14
0.4.13
0.4.12
0.4.11
0.4.10
0.4.9
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.29
0.3.28
0.3.27
0.3.26
0.3.25
0.3.24
0.3.23
0.3.22
0.3.21
0.3.20
0.3.19
0.3.18
0.3.17
0.3.16
0.3.15
0.3.14
0.3.13
0.3.12
0.3.11
0.3.10
0.3.9
0.3.8
0.3.7
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.20
0.1.19
0.1.18
0.1.17
0.1.16
0.1.15
0.1.14
0.1.13
0.1.12
0.1.11
0.1.10
0.1.9
0.1.8
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
Writes data to "stdio" in a table with borders and colors. Can choose a table style to change the look of the table.
Current section
Files
Jump to
Current section
Files
lib/io/ansi/table/spec_server.ex
defmodule IO.ANSI.Table.SpecServer do
@moduledoc """
A server process that holds a table `spec` struct as its state.
"""
use GenServer, restart: :transient
use PersistConfig
alias __MODULE__
alias IO.ANSI.Table.{Log, Spec}
@ets get_env(:ets_name)
@reg get_env(:registry)
@wait 50
@doc """
Spawns a new table spec server process to be registered via a `spec name`.
"""
@spec start_link(Spec.t()) :: GenServer.on_start()
def start_link(spec) do
GenServer.start_link(SpecServer, spec, name: via(spec.spec_name))
end
@doc """
Allows to register or look up a table spec server process via a `spec name`.
"""
@spec via(String.t()) :: {:via, Registry, tuple}
def via(spec_name), do: {:via, Registry, {@reg, key(spec_name)}}
## Private functions
@spec key(String.t()) :: tuple
defp key(spec_name), do: {SpecServer, spec_name}
@spec extend(Spec.t()) :: Spec.t()
defp extend(spec) do
case :ets.lookup(@ets, key(spec.spec_name)) do
[] ->
:ok = Log.info(:spawned, {spec})
Spec.extend(spec) |> save()
[{_key, spec}] ->
:ok = Log.info(:restarted, {spec})
spec
end
end
@spec save(Spec.t()) :: Spec.t()
defp save(spec) do
:ok = Log.info(:save, {spec, __ENV__})
true = :ets.insert(@ets, {key(spec.spec_name), spec})
spec
end
## Callbacks
@spec init(Spec.t()) :: {:ok, Spec.t()}
def init(spec), do: {:ok, extend(spec)}
@spec handle_cast(term, Spec.t()) :: {:noreply, Spec.t()}
def handle_cast({:write, maps, options} = request, spec) do
:ok = Log.info(:handle_cast, {spec, request, __ENV__})
:ok = Spec.write_table(spec, maps, options)
{:noreply, spec}
end
@spec handle_call(term, GenServer.from(), Spec.t()) ::
{:reply, :ok | Spec.t(), Spec.t()}
def handle_call({:format, maps, options} = request, {from_pid, _tag}, spec) do
group_leader = Process.info(from_pid)[:group_leader]
if group_leader, do: self() |> Process.group_leader(group_leader)
:ok = Log.info(:handle_call, {spec, request, __ENV__})
:ok = Spec.write_table(spec, maps, options)
{:reply, :ok, spec}
end
def handle_call(:get = request, _from, spec) do
:ok = Log.info(:handle_call, {spec, request, __ENV__})
{:reply, spec, spec}
end
@spec terminate(term, Spec.t()) :: :ok
def terminate(:shutdown = reason, spec) do
:ok = Log.info(:terminate, {reason, spec, __ENV__})
true = :ets.delete(@ets, key(spec.spec_name))
# Ensure message logged before exiting...
Process.sleep(@wait)
end
def terminate(reason, spec) do
:ok = Log.error(:terminate, {reason, spec, __ENV__})
true = :ets.delete(@ets, key(spec.spec_name))
# Ensure message logged before exiting...
Process.sleep(@wait)
end
end