Skip to content

Commit 6acd396

Browse files
committed
Support Jason.encode!(data, pretty: true)
1 parent e65827a commit 6acd396

File tree

3 files changed

+40
-7
lines changed

3 files changed

+40
-7
lines changed

lib/jason.ex

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,19 @@ defmodule Jason do
33
A blazing fast JSON parser and generator in pure Elixir.
44
"""
55

6+
alias Jason.{Encode, Decoder, DecodeError, EncodeError, Formatter}
7+
68
@type escape :: :json | :unicode_safe | :html_safe | :javascript_safe
79
@type maps :: :naive | :strict
810

9-
@type encode_opt :: {:escape, escape} | {:maps, maps}
11+
@type encode_opt :: {:escape, escape} | {:maps, maps} | {:pretty, true | Formatter.opts()}
1012

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

1315
@type strings :: :reference | :copy
1416

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

17-
alias Jason.{Encode, Decoder, DecodeError, EncodeError}
18-
1919
@doc """
2020
Parses a JSON value from `input` iodata.
2121
@@ -105,6 +105,11 @@ defmodule Jason do
105105
rejected, since both keys would be encoded to the string `"foo"`.
106106
* `:naive` (default) - does not perform the check.
107107
108+
* `:pretty` - controls pretty printing of the output. Possible values are:
109+
110+
* `true` to pretty print with default configuration
111+
* a keyword of options as specified by `Jason.Formatter.pretty_print/2`.
112+
108113
## Examples
109114
110115
iex> Jason.encode(%{a: 1})
@@ -117,7 +122,7 @@ defmodule Jason do
117122
@spec encode(term, [encode_opt]) ::
118123
{:ok, String.t()} | {:error, EncodeError.t() | Exception.t()}
119124
def encode(input, opts \\ []) do
120-
case Encode.encode(input, format_encode_opts(opts)) do
125+
case do_encode(input, format_encode_opts(opts)) do
121126
{:ok, result} -> {:ok, IO.iodata_to_binary(result)}
122127
{:error, error} -> {:error, error}
123128
end
@@ -140,7 +145,7 @@ defmodule Jason do
140145
"""
141146
@spec encode!(term, [encode_opt]) :: String.t() | no_return
142147
def encode!(input, opts \\ []) do
143-
case Encode.encode(input, format_encode_opts(opts)) do
148+
case do_encode(input, format_encode_opts(opts)) do
144149
{:ok, result} -> IO.iodata_to_binary(result)
145150
{:error, error} -> raise error
146151
end
@@ -168,7 +173,7 @@ defmodule Jason do
168173
@spec encode_to_iodata(term, [encode_opt]) ::
169174
{:ok, iodata} | {:error, EncodeError.t() | Exception.t()}
170175
def encode_to_iodata(input, opts \\ []) do
171-
Encode.encode(input, format_encode_opts(opts))
176+
do_encode(input, format_encode_opts(opts))
172177
end
173178

174179
@doc """
@@ -189,12 +194,30 @@ defmodule Jason do
189194
"""
190195
@spec encode_to_iodata!(term, [encode_opt]) :: iodata | no_return
191196
def encode_to_iodata!(input, opts \\ []) do
192-
case Encode.encode(input, format_encode_opts(opts)) do
197+
case do_encode(input, format_encode_opts(opts)) do
193198
{:ok, result} -> result
194199
{:error, error} -> raise error
195200
end
196201
end
197202

203+
defp do_encode(input, %{pretty: true} = opts) do
204+
case Encode.encode(input, opts) do
205+
{:ok, encoded} -> {:ok, Formatter.pretty_print_to_iodata(encoded)}
206+
other -> other
207+
end
208+
end
209+
210+
defp do_encode(input, %{pretty: pretty} = opts) do
211+
case Encode.encode(input, opts) do
212+
{:ok, encoded} -> {:ok, Formatter.pretty_print_to_iodata(encoded, pretty)}
213+
other -> other
214+
end
215+
end
216+
217+
defp do_encode(input, opts) do
218+
Encode.encode(input, opts)
219+
end
220+
198221
defp format_encode_opts(opts) do
199222
Enum.into(opts, %{escape: :json, maps: :naive})
200223
end

test/encode_test.exs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,10 @@ defmodule Jason.EncoderTest do
151151
assert {:error, %Protocol.UndefinedError{}} = Jason.encode(self())
152152
end
153153

154+
test "pretty: true" do
155+
assert to_json(%{a: 3.14159, b: 1}, pretty: true) == ~s|{\n "a": 3.14159,\n "b": 1\n}|
156+
end
157+
154158
defp to_json(value, opts \\ []) do
155159
Jason.encode!(value, opts)
156160
end

test/property_test.exs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ if Code.ensure_loaded?(ExUnitProperties) do
3333
end
3434
end
3535

36+
property "pretty roundtrip" do
37+
check all json <- json(string(:printable)) do
38+
assert decode(encode(json, pretty: true)) == json
39+
end
40+
end
41+
3642
property "unicode escaping" do
3743
check all string <- string(:printable) do
3844
encoded = encode(string, escape: :unicode)

0 commit comments

Comments
 (0)