Skip to content

Instantly share code, notes, and snippets.

@mustafaturan
Last active August 6, 2018 17:48
Show Gist options
  • Save mustafaturan/eb7ed26f0e4b6a4d223d15bcb4f23ae2 to your computer and use it in GitHub Desktop.
Save mustafaturan/eb7ed26f0e4b6a4d223d15bcb4f23ae2 to your computer and use it in GitHub Desktop.
Wrapper for the fastest Elixir JSON encode/decode library
defmodule JSON do
@moduledoc false
@encode_opts [:use_nil]
@decode_opts [:return_maps, :use_nil]
alias :jiffy, as: Jiffy
@doc """
Encode and return tuple
"""
@spec encode(any) :: {:ok, Strint.t()} | {:error, tuple()}
def encode(nil) do
{:ok, nil}
end
def encode(payload) do
{:ok, Jiffy.encode(payload, @encode_opts)}
catch
{:error, reason} -> {:error, reason}
end
@doc """
Encode and return encoded json
"""
@spec encode!(any) :: Strint.t() | {:error, tuple()}
def encode!(payload) do
case encode(payload) do
{:ok, json} -> json
{:error, reason} -> {:error, reason}
end
end
@doc """
Decode and return tuple
"""
@spec decode(String.t() | nil) :: {:ok, Map.t() | list()} | {:error, tuple()}
def decode(payload) do
{:ok, Jiffy.decode("#{payload}", @decode_opts)}
catch
{:error, reason} -> {:error, reason}
end
@doc """
Decode and return decoded data
"""
@spec decode!(String.t() | nil) :: Map.t() | list() | {:error, tuple()}
def decode!(payload) do
case decode(payload) do
{:ok, data} -> data
{:error, reason} -> {:error, reason}
end
end
@doc """
Convert map string keys to atom keys
This function is an optional to atomize map keys instead of having
string keys.
Warning: By default, the maximum number of atoms is 1,048,576.
This function should be used responsibly. Personally,
I recommend to use this function if you only can validate
the JSON schemas.
"""
@spec atomize_keys(any()) :: any()
# Walk through the map
def atomize_keys(map = %{}) do
map
|> Enum.map(fn {k, v} -> {to_atom(k), atomize_keys(v)} end)
|> Enum.into(%{})
end
# Walk through the list
def atomize_keys([head | rest]) do
[atomize_keys(head) | atomize_keys(rest)]
end
# Other data types
def atomize_keys(other) do
other
end
defp to_atom(key) when is_atom(key) do
key
end
defp to_atom(key) when is_binary(key) do
String.to_atom(key)
end
defp to_atom(key) do
key
end
end
@shribe
Copy link

shribe commented Jul 19, 2018

encode! & decode! should return data or raise; there is no point in having those calls if callers still need to patter match on the returned values

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment