Add tableformatter
this is the preferred approach according to the book
This commit is contained in:
parent
53624e0bbf
commit
d1bc22f745
|
@ -1,4 +1,7 @@
|
|||
defmodule Issues.CLI do
|
||||
|
||||
import Issues.TableFormatter, only: [print_table_for_columns: 2]
|
||||
|
||||
@default_count 4
|
||||
|
||||
@moduledoc """
|
||||
|
@ -54,7 +57,7 @@ defmodule Issues.CLI do
|
|||
|> decode_response()
|
||||
|> sort_into_descending_order
|
||||
|> last(count)
|
||||
|> show_issues_as_table
|
||||
|> show_issues_as_table # alternative: print_table_for_columns(["id", "created_at", "title"])
|
||||
end
|
||||
|
||||
def decode_response({:ok, body}), do: body
|
||||
|
@ -100,12 +103,12 @@ defmodule Issues.CLI do
|
|||
|
||||
# print the title
|
||||
IO.puts(
|
||||
"#{String.pad_trailing("#id", id_column_width)} | #{String.pad_trailing("created_at", creation_date_width)} | #{String.pad_trailing("title", title_length)} "
|
||||
"#{String.pad_trailing("#id", id_column_width)} | #{String.pad_trailing("created_at", creation_date_width)} | #{String.pad_trailing("title", title_length)}"
|
||||
)
|
||||
|
||||
# print seperator
|
||||
IO.puts(
|
||||
"#{String.pad_trailing("-", id_column_width, "-")}-+-#{String.pad_trailing("-", creation_date_width, "-")}-+-#{String.pad_trailing("-", title_length, "-")}-"
|
||||
"#{String.duplicate("-", id_column_width)}-+-#{String.duplicate("-", creation_date_width)}-+-#{String.duplicate("-", title_length)}"
|
||||
)
|
||||
|
||||
# print each issue
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
defmodule Issues.TableFormatter do
|
||||
import Enum, only: [each: 2, map: 2, map_join: 3, max: 1]
|
||||
|
||||
def print_table_for_columns(rows, headers) do
|
||||
with data_by_columns = split_into_columns(rows, headers),
|
||||
column_widths = widths_of(data_by_columns),
|
||||
format = format_for(column_widths) do
|
||||
puts_one_line_in_columns(headers, format)
|
||||
IO.puts(separator(column_widths))
|
||||
puts_in_columns(data_by_columns, format)
|
||||
end
|
||||
end
|
||||
|
||||
def split_into_columns(rows, headers) do
|
||||
for header <- headers do
|
||||
for row <- rows, do: printable(row[header])
|
||||
end
|
||||
end
|
||||
|
||||
def printable(str) when is_binary(str), do: str
|
||||
def printable(str), do: to_string(str)
|
||||
|
||||
def widths_of(columns) do
|
||||
for column <- columns, do: column |> map(&String.length/1) |> max
|
||||
end
|
||||
|
||||
def format_for(columns_width) do
|
||||
map_join(columns_width, " | ", fn width -> "~-#{width}s" end) <> "~n"
|
||||
end
|
||||
|
||||
def separator(column_widths) do
|
||||
map_join(column_widths, "-+-", fn width -> List.duplicate("-", width) end)
|
||||
end
|
||||
|
||||
def puts_in_columns(data_by_columns, format) do
|
||||
data_by_columns
|
||||
|> List.zip()
|
||||
|> map(&Tuple.to_list/1)
|
||||
|> each(&puts_one_line_in_columns(&1, format))
|
||||
end
|
||||
|
||||
def puts_one_line_in_columns(fields, format) do
|
||||
:io.format(format, fields)
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue