Skip to content

Commit

Permalink
Support Jason.encode!(data, pretty: true)
Browse files Browse the repository at this point in the history
  • Loading branch information
michalmuskala committed Jul 2, 2018
1 parent e65827a commit 6acd396
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 7 deletions.
37 changes: 30 additions & 7 deletions lib/jason.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@ defmodule Jason do
A blazing fast JSON parser and generator in pure Elixir.
"""

alias Jason.{Encode, Decoder, DecodeError, EncodeError, Formatter}

@type escape :: :json | :unicode_safe | :html_safe | :javascript_safe
@type maps :: :naive | :strict

@type encode_opt :: {:escape, escape} | {:maps, maps}
@type encode_opt :: {:escape, escape} | {:maps, maps} | {:pretty, true | Formatter.opts()}

@type keys :: :atoms | :atoms! | :strings | :copy | (String.t() -> term)

@type strings :: :reference | :copy

@type decode_opt :: {:keys, keys} | {:strings, strings}

alias Jason.{Encode, Decoder, DecodeError, EncodeError}

@doc """
Parses a JSON value from `input` iodata.
Expand Down Expand Up @@ -105,6 +105,11 @@ defmodule Jason do
rejected, since both keys would be encoded to the string `"foo"`.
* `:naive` (default) - does not perform the check.
* `:pretty` - controls pretty printing of the output. Possible values are:
* `true` to pretty print with default configuration
* a keyword of options as specified by `Jason.Formatter.pretty_print/2`.
## Examples
iex> Jason.encode(%{a: 1})
Expand All @@ -117,7 +122,7 @@ defmodule Jason do
@spec encode(term, [encode_opt]) ::
{:ok, String.t()} | {:error, EncodeError.t() | Exception.t()}
def encode(input, opts \\ []) do
case Encode.encode(input, format_encode_opts(opts)) do
case do_encode(input, format_encode_opts(opts)) do
{:ok, result} -> {:ok, IO.iodata_to_binary(result)}
{:error, error} -> {:error, error}
end
Expand All @@ -140,7 +145,7 @@ defmodule Jason do
"""
@spec encode!(term, [encode_opt]) :: String.t() | no_return
def encode!(input, opts \\ []) do
case Encode.encode(input, format_encode_opts(opts)) do
case do_encode(input, format_encode_opts(opts)) do
{:ok, result} -> IO.iodata_to_binary(result)
{:error, error} -> raise error
end
Expand Down Expand Up @@ -168,7 +173,7 @@ defmodule Jason do
@spec encode_to_iodata(term, [encode_opt]) ::
{:ok, iodata} | {:error, EncodeError.t() | Exception.t()}
def encode_to_iodata(input, opts \\ []) do
Encode.encode(input, format_encode_opts(opts))
do_encode(input, format_encode_opts(opts))
end

@doc """
Expand All @@ -189,12 +194,30 @@ defmodule Jason do
"""
@spec encode_to_iodata!(term, [encode_opt]) :: iodata | no_return
def encode_to_iodata!(input, opts \\ []) do
case Encode.encode(input, format_encode_opts(opts)) do
case do_encode(input, format_encode_opts(opts)) do
{:ok, result} -> result
{:error, error} -> raise error
end
end

defp do_encode(input, %{pretty: true} = opts) do
case Encode.encode(input, opts) do
{:ok, encoded} -> {:ok, Formatter.pretty_print_to_iodata(encoded)}
other -> other
end
end

defp do_encode(input, %{pretty: pretty} = opts) do
case Encode.encode(input, opts) do
{:ok, encoded} -> {:ok, Formatter.pretty_print_to_iodata(encoded, pretty)}
other -> other
end
end

defp do_encode(input, opts) do
Encode.encode(input, opts)
end

defp format_encode_opts(opts) do
Enum.into(opts, %{escape: :json, maps: :naive})
end
Expand Down
4 changes: 4 additions & 0 deletions test/encode_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ defmodule Jason.EncoderTest do
assert {:error, %Protocol.UndefinedError{}} = Jason.encode(self())
end

test "pretty: true" do
assert to_json(%{a: 3.14159, b: 1}, pretty: true) == ~s|{\n "a": 3.14159,\n "b": 1\n}|
end

defp to_json(value, opts \\ []) do
Jason.encode!(value, opts)
end
Expand Down
6 changes: 6 additions & 0 deletions test/property_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ if Code.ensure_loaded?(ExUnitProperties) do
end
end

property "pretty roundtrip" do
check all json <- json(string(:printable)) do
assert decode(encode(json, pretty: true)) == json
end
end

property "unicode escaping" do
check all string <- string(:printable) do
encoded = encode(string, escape: :unicode)
Expand Down

0 comments on commit 6acd396

Please sign in to comment.