1defprotocol Apex.Format do
2  @fallback_to_any true
3  def format(data, options \\ [])
4end
5
6defimpl Apex.Format, for: Reference do
7  import Apex.Format.Utils
8
9  def format(data, options \\ []) do
10    colorize(inspect(data), data, options) <> new_line()
11  end
12end
13
14defimpl Apex.Format, for: BitString do
15  import Apex.Format.Utils
16
17  def format(data, options \\ []) do
18    case String.valid?(data) do
19      true ->
20        colorize("\"#{data}\"", data, options) <> new_line()
21      false ->
22        colorize("#{inspect data}", data, options) <> new_line()
23    end
24  end
25end
26
27defimpl Apex.Format, for: Integer do
28  import Apex.Format.Utils
29
30  def format(data, options \\ []) do
31    colorize("#{data}", data, options) <> new_line()
32  end
33end
34
35defimpl Apex.Format, for: Float do
36  import Apex.Format.Utils
37
38  def format(data, options \\ []) do
39    colorize("#{:erlang.float_to_binary(data, [:compact, decimals: 15])}", data, options) <> new_line()
40  end
41end
42
43defimpl Apex.Format, for: Atom do
44  import Apex.Format.Utils
45
46  def format(data, options \\ [])
47
48  def format(data, options) when data in [true, false, nil] do
49    colorize(Atom.to_string(data), data, options) <> new_line()
50  end
51
52  def format(data, options) do
53    colorize(":" <> Atom.to_string(data), data, options) <> new_line()
54  end
55end
56
57defimpl Apex.Format, for: List do
58  import Apex.Format.Utils
59
60  def format(data, options \\ [])
61
62  def format([], options) do
63    colorize("[]", [], options) <> new_line()
64  end
65
66  def format(data, options) do
67    Apex.Format.Seq.format(data, options)
68  end
69end
70
71defimpl Apex.Format, for: Range do
72  import Apex.Format.Utils
73
74  def format(d = %{__struct__: name, first: lower_bound, last: upper_bound}, options \\ []) do
75    colorize("##{name} #{lower_bound}..#{upper_bound}", d, options) <> new_line()
76  end
77end
78
79defimpl Apex.Format, for: PID do
80  import Apex.Format.Utils
81
82  def format(data, options \\ []) do
83    colorize(inspect(data), data, options) <> new_line()
84  end
85end
86
87defimpl Apex.Format, for: Port do
88  import Apex.Format.Utils
89
90  def format(data, options \\ []) do
91    colorize(inspect(data), data, options) <> new_line()
92  end
93end
94
95defimpl Apex.Format, for: Function do
96  import Apex.Format.Utils
97
98  def format(data, options \\ []) do
99    colorize(inspect(data), data, options) <> new_line()
100  end
101end
102
103defimpl Apex.Format, for: MapSet do
104  def format(data, options \\ []) do
105    Apex.Format.Seq.format_set("MapSet", data, options)
106  end
107end
108
109defimpl Apex.Format, for: Map do
110  import Apex.Format.Utils
111
112  def format(data, options \\ [])
113
114  def format(data, options) when data == %{} do
115    colorize("%{}", %{}, options) <> new_line()
116  end
117
118  def format(data, options) do
119    Apex.Format.Seq.format(
120      Map.to_list(data),
121      options,
122      start_token: "\%{",
123      end_token: "}",
124      numbers: false) |> colorize(data, options)
125  end
126end
127
128defimpl Apex.Format, for: Any do
129  import Apex.Format.Utils
130
131  def format(data = %{__struct__: name}, options \\ []) when is_map(data) do
132    Apex.Format.Seq.format(
133      Map.delete(data, :__struct__) |> Map.to_list,
134      options,
135      start_token: "\%#{name}{",
136      end_token: "}",
137      numbers: false) |> colorize(data, options)
138  end
139end
140