-
-
Save akoutmos/f14e0f719b4efbee2526858b34869004 to your computer and use it in GitHub Desktop.
Pretty print JSON passed via STDIN using Elixir shell script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env elixir | |
# Install required deps | |
Mix.install([:jason]) | |
# The pretty printing module | |
defmodule JsonPrettyPrinter do | |
def get_stdin_data do | |
# Fetch data from STDIN and decode JSON | |
:stdio | |
|> IO.read(:all) | |
|> Jason.decode() | |
|> case do | |
{:ok, json_data} -> json_data | |
_ -> raise "Invalid JSON payload was provided" | |
end | |
end | |
def pretty_print_json(data) do | |
body = | |
data | |
|> Enum.to_list() | |
|> Enum.sort() | |
|> Enum.map(fn {key, value} -> | |
~s/ #{color_data(:green, key)}#{color_data(:yellow, ":")} #{pretty_print(value, 1)}/ | |
end) | |
|> Enum.join(",\n") | |
""" | |
#{color_data(:yellow, "{")} | |
#{body} | |
#{color_data(:yellow, "}")} | |
""" | |
end | |
def pretty_print(current_data, _indent_level) when is_number(current_data) do | |
color_data(:blue, current_data) | |
end | |
def pretty_print(current_data, _indent_level) when is_boolean(current_data) do | |
color_data(:magenta, current_data) | |
end | |
def pretty_print(current_data, _indent_level) when is_binary(current_data) do | |
color_data(:cyan, ~s/"#{current_data}"/) | |
end | |
def pretty_print(current_data, _indent_level) when is_nil(current_data) do | |
color_data(:red, "null") | |
end | |
def pretty_print(current_data, _indent_level) when current_data == %{} do | |
color_data(:yellow, "{}") | |
end | |
def pretty_print(current_data, _indent_level) when current_data == [] do | |
color_data(:yellow, "[]") | |
end | |
def pretty_print(current_data, indent_level) when is_list(current_data) do | |
indent_padding = String.duplicate(" ", indent_level * 2) | |
next_indent_padding = String.duplicate(" ", (indent_level + 1) * 2) | |
body = | |
current_data | |
|> Enum.sort() | |
|> Enum.map(fn element -> | |
~s/#{next_indent_padding}#{pretty_print(element, indent_level + 1)}/ | |
end) | |
|> Enum.join(",\n") | |
Enum.join( | |
[ | |
color_data(:yellow, "["), | |
body, | |
"#{indent_padding}#{color_data(:yellow, "]")}" | |
], | |
"\n" | |
) | |
end | |
def pretty_print(current_data, indent_level) when is_map(current_data) do | |
indent_padding = String.duplicate(" ", indent_level * 2) | |
next_indent_padding = String.duplicate(" ", (indent_level + 1) * 2) | |
body = | |
current_data | |
|> Enum.to_list() | |
|> Enum.sort() | |
|> Enum.map(fn {key, value} -> | |
~s/#{next_indent_padding}#{color_data(:green, key)}#{color_data(:yellow, ":")} #{pretty_print(value, indent_level + 1)}/ | |
end) | |
|> Enum.join(",\n") | |
Enum.join( | |
[ | |
color_data(:yellow, "{"), | |
body, | |
"#{indent_padding}#{color_data(:yellow, "}")}" | |
], | |
"\n" | |
) | |
end | |
defp color_data(:red, data), do: IO.ANSI.red() <> "#{data}" <> IO.ANSI.reset() | |
defp color_data(:blue, data), do: IO.ANSI.blue() <> "#{data}" <> IO.ANSI.reset() | |
defp color_data(:cyan, data), do: IO.ANSI.cyan() <> "#{data}" <> IO.ANSI.reset() | |
defp color_data(:magenta, data), do: IO.ANSI.magenta() <> "#{data}" <> IO.ANSI.reset() | |
defp color_data(:green, data), do: IO.ANSI.green() <> "#{data}" <> IO.ANSI.reset() | |
defp color_data(:yellow, data), do: IO.ANSI.yellow() <> "#{data}" <> IO.ANSI.reset() | |
defp color_data(:white, data), do: IO.ANSI.white() <> "#{data}" <> IO.ANSI.reset() | |
end | |
# Perform the pretty printing | |
JsonPrettyPrinter.get_stdin_data() | |
|> JsonPrettyPrinter.pretty_print_json() | |
|> IO.puts() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment