@@ -10,12 +10,11 @@ defmodule Jason.Formatter do
10
10
"""
11
11
12
12
@ type opts :: [
13
- { :indent , iodata } |
14
- { :line_separator , iodata } |
15
- { :record_separator , iodata } |
16
- { :after_colon , iodata }
17
- ]
18
-
13
+ { :indent , iodata }
14
+ | { :line_separator , iodata }
15
+ | { :record_separator , iodata }
16
+ | { :after_colon , iodata }
17
+ ]
19
18
20
19
@ doc ~S"""
21
20
Returns a binary containing a pretty-printed representation of
@@ -51,10 +50,9 @@ defmodule Jason.Formatter do
51
50
@ spec pretty_print ( iodata , opts ) :: binary
52
51
def pretty_print ( iodata , opts \\ [ ] ) do
53
52
pretty_print_to_iodata ( iodata , opts )
54
- |> IO . iodata_to_binary
53
+ |> IO . iodata_to_binary ( )
55
54
end
56
55
57
-
58
56
@ doc ~S"""
59
57
Returns an iolist containing a pretty-printed representation of
60
58
JSON-encoded `iodata`.
@@ -70,13 +68,11 @@ defmodule Jason.Formatter do
70
68
first = true
71
69
opts = normalize_opts ( opts )
72
70
73
- { output , _state } =
74
- pp_iodata ( iodata , [ ] , depth , in_str , in_bs , empty , first , opts )
71
+ { output , _state } = pp_iodata ( iodata , [ ] , depth , in_str , in_bs , empty , first , opts )
75
72
76
73
output
77
74
end
78
75
79
-
80
76
@ doc ~S"""
81
77
Returns a binary containing a minimized representation of
82
78
JSON-encoded `iodata`.
@@ -96,10 +92,9 @@ defmodule Jason.Formatter do
96
92
@ spec minimize ( iodata , opts ) :: binary
97
93
def minimize ( iodata , opts \\ [ ] ) do
98
94
minimize_to_iodata ( iodata , opts )
99
- |> IO . iodata_to_binary
95
+ |> IO . iodata_to_binary ( )
100
96
end
101
97
102
-
103
98
@ doc ~S"""
104
99
Returns an iolist containing a minimized representation of
105
100
JSON-encoded `iodata`.
@@ -117,48 +112,57 @@ defmodule Jason.Formatter do
117
112
)
118
113
end
119
114
120
-
121
115
## Returns a copy of `opts` with defaults applied
122
116
@ spec normalize_opts ( keyword ) :: opts
123
117
defp normalize_opts ( opts ) do
124
118
[
125
119
indent: opts [ :indent ] || " " ,
126
120
line_separator: opts [ :line_separator ] || "\n " ,
127
121
record_separator: opts [ :record_separator ] || opts [ :line_separator ] || "\n " ,
128
- after_colon: opts [ :after_colon ] || " " ,
122
+ after_colon: opts [ :after_colon ] || " "
129
123
]
130
124
end
131
125
132
-
133
126
## Returns an iolist containing `depth` instances of `opts[:indent]`
134
127
@ spec tab ( opts , non_neg_integer , iolist ) :: iolist
135
128
defp tab ( opts , depth , output \\ [ ] ) do
136
129
if depth < 1 do
137
130
output
138
131
else
139
- tab ( opts , depth - 1 , [ opts [ :indent ] | output ] )
132
+ tab ( opts , depth - 1 , [ opts [ :indent ] | output ] )
140
133
end
141
134
end
142
135
143
-
144
136
@ typep pp_state :: {
145
- non_neg_integer , ## depth -- current nesting depth
146
- boolean , ## in_str -- is the current byte in a string?
147
- boolean , ## in_bs -- does the current byte follow a backslash in a string?
148
- boolean , ## empty -- is the current object or array empty?
149
- boolean , ## first -- is this the first object or array in the input?
150
- }
137
+ ## depth -- current nesting depth
138
+ non_neg_integer ,
139
+ ## in_str -- is the current byte in a string?
140
+ boolean ,
141
+ ## in_bs -- does the current byte follow a backslash in a string?
142
+ boolean ,
143
+ ## empty -- is the current object or array empty?
144
+ boolean ,
145
+ ## first -- is this the first object or array in the input?
146
+ boolean
147
+ }
151
148
152
149
@ spec pp_iodata (
153
- iodata , ## input -- input data
154
- iodata , ## output_acc -- output iolist (built in reverse order)
155
- non_neg_integer , ## depth -- current nesting depth
156
- boolean , ## in_str -- is the current byte in a string?
157
- boolean , ## in_bs -- does the current byte follow a backslash in a string?
158
- boolean , ## empty -- is the current object or array empty?
159
- boolean , ## first -- is this the first object or array in the input?
160
- opts
161
- ) :: { iodata , pp_state }
150
+ ## input -- input data
151
+ iodata ,
152
+ ## output_acc -- output iolist (built in reverse order)
153
+ iodata ,
154
+ ## depth -- current nesting depth
155
+ non_neg_integer ,
156
+ ## in_str -- is the current byte in a string?
157
+ boolean ,
158
+ ## in_bs -- does the current byte follow a backslash in a string?
159
+ boolean ,
160
+ ## empty -- is the current object or array empty?
161
+ boolean ,
162
+ ## first -- is this the first object or array in the input?
163
+ boolean ,
164
+ opts
165
+ ) :: { iodata , pp_state }
162
166
defp pp_iodata ( input , output_acc , depth , in_str , in_bs , empty , first , opts )
163
167
164
168
defp pp_iodata ( "" , output_acc , depth , in_str , in_bs , empty , first , opts ) do
@@ -169,111 +173,133 @@ defmodule Jason.Formatter do
169
173
{ output_acc , { depth , in_str , in_bs , empty , first , opts } }
170
174
end
171
175
172
- defp pp_iodata ( << byte :: size ( 8 ) , rest :: binary >> , output_acc , depth , in_str , in_bs , empty , first , opts ) do
176
+ defp pp_iodata (
177
+ << byte :: size ( 8 ) , rest :: binary >> ,
178
+ output_acc ,
179
+ depth ,
180
+ in_str ,
181
+ in_bs ,
182
+ empty ,
183
+ first ,
184
+ opts
185
+ ) do
173
186
pp_byte ( byte , rest , output_acc , depth , in_str , in_bs , empty , first , opts )
174
187
end
175
188
176
- defp pp_iodata ( byte , output_acc , depth , in_str , in_bs , empty , first , opts ) when is_integer ( byte ) do
189
+ defp pp_iodata ( byte , output_acc , depth , in_str , in_bs , empty , first , opts )
190
+ when is_integer ( byte ) do
177
191
pp_byte ( byte , [ ] , output_acc , depth , in_str , in_bs , empty , first , opts )
178
192
end
179
193
180
194
defp pp_iodata ( list , output_acc , depth , in_str , in_bs , empty , first , opts ) when is_list ( list ) do
181
195
starting_state = { depth , in_str , in_bs , empty , first , opts }
182
- { reversed_output , end_state } = Enum . reduce list , { [ ] , starting_state } , fn ( item , { output_acc , state } ) ->
183
- { depth , in_str , in_bs , empty , first , opts } = state
184
- { item_output , new_state } = pp_iodata ( item , [ ] , depth , in_str , in_bs , empty , first , opts )
185
- { [ output_acc , item_output ] , new_state }
186
- end
187
- { [ output_acc , reversed_output ] , end_state }
188
- end
189
196
197
+ { list_output , end_state } =
198
+ Enum . reduce ( list , { [ ] , starting_state } , fn item , { output_acc , state } ->
199
+ { depth , in_str , in_bs , empty , first , opts } = state
200
+ { item_output , new_state } = pp_iodata ( item , [ ] , depth , in_str , in_bs , empty , first , opts )
201
+ { [ output_acc , item_output ] , new_state }
202
+ end )
203
+
204
+ { [ output_acc , list_output ] , end_state }
205
+ end
190
206
191
207
@ spec pp_byte (
192
- byte , ## byte -- current byte
193
- iodata , ## rest -- rest of input data
194
- iodata , ## output -- output iolist (built in reverse order)
195
- non_neg_integer , ## depth -- current nesting depth
196
- boolean , ## in_str -- is the current byte in a string?
197
- boolean , ## in_bs -- does the current byte follow a backslash in a string?
198
- boolean , ## empty -- is the current object or array empty?
199
- boolean , ## first -- is this the first object or array in the input?
200
- opts
201
- ) :: { iodata , pp_state }
208
+ ## byte -- current byte
209
+ byte ,
210
+ ## rest -- rest of input data
211
+ iodata ,
212
+ ## output -- output iolist (built in reverse order)
213
+ iodata ,
214
+ ## depth -- current nesting depth
215
+ non_neg_integer ,
216
+ ## in_str -- is the current byte in a string?
217
+ boolean ,
218
+ ## in_bs -- does the current byte follow a backslash in a string?
219
+ boolean ,
220
+ ## empty -- is the current object or array empty?
221
+ boolean ,
222
+ ## first -- is this the first object or array in the input?
223
+ boolean ,
224
+ opts
225
+ ) :: { iodata , pp_state }
202
226
defp pp_byte ( byte , rest , output , depth , in_str , in_bs , empty , first , opts )
203
227
204
228
## in string, following backslash
205
- defp pp_byte ( byte , rest , output , depth , true = in_str , true = _in_bs , empty , first , opts ) do
229
+ defp pp_byte ( byte , rest , output , depth , true = in_str , true = _in_bs , empty , first , opts ) do
206
230
in_bs = false
207
231
pp_iodata ( rest , [ output , byte ] , depth , in_str , in_bs , empty , first , opts )
208
232
end
209
233
210
234
## in string, backslash
211
- defp pp_byte ( byte , rest , output , depth , true = in_str , _in_bs , empty , first , opts )
212
- when byte in '\\ ' do
235
+ defp pp_byte ( byte , rest , output , depth , true = in_str , _in_bs , empty , first , opts )
236
+ when byte in '\\ ' do
213
237
in_bs = true
214
238
pp_iodata ( rest , [ output , byte ] , depth , in_str , in_bs , empty , first , opts )
215
239
end
216
240
217
241
## in string, end quote
218
- defp pp_byte ( byte , rest , output , depth , true = _in_str , in_bs , empty , first , opts )
219
- when byte in '"' do
242
+ defp pp_byte ( byte , rest , output , depth , true = _in_str , in_bs , empty , first , opts )
243
+ when byte in '"' do
220
244
in_str = false
221
245
pp_iodata ( rest , [ output , byte ] , depth , in_str , in_bs , empty , first , opts )
222
246
end
223
247
224
248
## in string, other character
225
- defp pp_byte ( byte , rest , output , depth , true = in_str , in_bs , empty , first , opts ) do
249
+ defp pp_byte ( byte , rest , output , depth , true = in_str , in_bs , empty , first , opts ) do
226
250
pp_iodata ( rest , [ output , byte ] , depth , in_str , in_bs , empty , first , opts )
227
251
end
228
252
229
253
## out of string, whitespace
230
254
defp pp_byte ( byte , rest , output , depth , in_str , in_bs , empty , first , opts )
231
- when byte in ' \n \r \t ' do
255
+ when byte in ' \n \r \t ' do
232
256
pp_iodata ( rest , output , depth , in_str , in_bs , empty , first , opts )
233
257
end
234
258
235
259
## out of string, start block
236
260
defp pp_byte ( byte , rest , output , depth , in_str , in_bs , empty , first , opts )
237
- when byte in '{[' do
238
- out = cond do
239
- first -> byte
240
- empty -> [ opts [ :line_separator ] , tab ( opts , depth ) , byte ]
241
- depth == 0 -> [ opts [ :record_separator ] , byte ]
242
- true -> byte
243
- end
261
+ when byte in '{[' do
262
+ out =
263
+ cond do
264
+ first -> byte
265
+ empty -> [ opts [ :line_separator ] , tab ( opts , depth ) , byte ]
266
+ depth == 0 -> [ opts [ :record_separator ] , byte ]
267
+ true -> byte
268
+ end
269
+
244
270
first = false
245
271
empty = true
246
272
depth = depth + 1
247
273
pp_iodata ( rest , [ output , out ] , depth , in_str , in_bs , empty , first , opts )
248
274
end
249
275
250
276
## out of string, end empty block
251
- defp pp_byte ( byte , rest , output , depth , in_str , in_bs , true = _empty , first , opts )
252
- when byte in '}]' do
277
+ defp pp_byte ( byte , rest , output , depth , in_str , in_bs , true = _empty , first , opts )
278
+ when byte in '}]' do
253
279
empty = false
254
280
depth = depth - 1
255
281
pp_iodata ( rest , [ output , byte ] , depth , in_str , in_bs , empty , first , opts )
256
282
end
257
283
258
284
## out of string, end non-empty block
259
- defp pp_byte ( byte , rest , output , depth , in_str , in_bs , false = empty , first , opts )
260
- when byte in '}]' do
285
+ defp pp_byte ( byte , rest , output , depth , in_str , in_bs , false = empty , first , opts )
286
+ when byte in '}]' do
261
287
depth = depth - 1
262
288
out = [ opts [ :line_separator ] , tab ( opts , depth ) , byte ]
263
289
pp_iodata ( rest , [ output , out ] , depth , in_str , in_bs , empty , first , opts )
264
290
end
265
291
266
292
## out of string, comma
267
293
defp pp_byte ( byte , rest , output , depth , in_str , in_bs , _empty , first , opts )
268
- when byte in ',' do
294
+ when byte in ',' do
269
295
empty = false
270
296
out = [ byte , opts [ :line_separator ] , tab ( opts , depth ) ]
271
297
pp_iodata ( rest , [ output , out ] , depth , in_str , in_bs , empty , first , opts )
272
298
end
273
299
274
300
## out of string, colon
275
301
defp pp_byte ( byte , rest , output , depth , in_str , in_bs , empty , first , opts )
276
- when byte in ':' do
302
+ when byte in ':' do
277
303
out = [ byte , opts [ :after_colon ] ]
278
304
pp_iodata ( rest , [ output , out ] , depth , in_str , in_bs , empty , first , opts )
279
305
end
@@ -286,4 +312,3 @@ defmodule Jason.Formatter do
286
312
pp_iodata ( rest , [ output , out ] , depth , in_str , in_bs , empty , first , opts )
287
313
end
288
314
end
289
-
0 commit comments