json 3.0.1 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES.md +13 -0
- data/ext/json/ext/fbuffer/fbuffer.h +4 -0
- data/ext/json/ext/generator/generator.c +156 -44
- data/ext/json/ext/json.h +6 -0
- data/ext/json/ext/parser/parser.c +59 -54
- data/lib/json/common.rb +26 -26
- data/lib/json/ext/generator/state.rb +2 -6
- data/lib/json/ext.rb +129 -3
- data/lib/json/truffle_ruby/generator.rb +110 -30
- data/lib/json/version.rb +1 -1
- data/lib/json.rb +45 -37
- metadata +2 -2
|
@@ -112,6 +112,8 @@ module JSON
|
|
|
112
112
|
# while generating a JSON text from a Ruby data structure.
|
|
113
113
|
class State
|
|
114
114
|
singleton_class.attr_accessor :default_sort_keys_proc # :nodoc:
|
|
115
|
+
singleton_class.attr_accessor :rfc8785_number_formatter_proc # :nodoc:
|
|
116
|
+
singleton_class.attr_accessor :rfc8785_sort_keys_proc # :nodoc:
|
|
115
117
|
|
|
116
118
|
def self.generate(obj, opts = nil, io = nil)
|
|
117
119
|
new(opts).generate(obj, io)
|
|
@@ -125,7 +127,7 @@ module JSON
|
|
|
125
127
|
if opts
|
|
126
128
|
case
|
|
127
129
|
when self === opts
|
|
128
|
-
return opts
|
|
130
|
+
return opts.validate_rfc8785
|
|
129
131
|
when opts.respond_to?(:to_hash)
|
|
130
132
|
return new(opts.to_hash)
|
|
131
133
|
when opts.respond_to?(:to_h)
|
|
@@ -168,6 +170,7 @@ module JSON
|
|
|
168
170
|
@max_nesting = 100
|
|
169
171
|
@sort_keys = false
|
|
170
172
|
@allow_duplicate_key = false
|
|
173
|
+
@rfc8785 = false
|
|
171
174
|
_configure(**opts) if opts
|
|
172
175
|
end
|
|
173
176
|
|
|
@@ -189,7 +192,16 @@ module JSON
|
|
|
189
192
|
attr_accessor :array_nl
|
|
190
193
|
|
|
191
194
|
# This proc converts unsupported types into native JSON types.
|
|
192
|
-
|
|
195
|
+
attr_reader :as_json
|
|
196
|
+
|
|
197
|
+
def as_json=(value)
|
|
198
|
+
raise FrozenError, "can't modify frozen #{self.class}: #{inspect}" if frozen?
|
|
199
|
+
value = value.to_proc if !(Proc === value) && value.respond_to?(:to_proc)
|
|
200
|
+
unless Proc === value
|
|
201
|
+
raise TypeError, "as_json must be a Proc"
|
|
202
|
+
end
|
|
203
|
+
@as_json = value
|
|
204
|
+
end
|
|
193
205
|
|
|
194
206
|
# This integer returns the maximum level of data structure nesting in
|
|
195
207
|
# the generated JSON, max_nesting = 0 if no maximum is checked.
|
|
@@ -209,6 +221,9 @@ module JSON
|
|
|
209
221
|
# desired order.
|
|
210
222
|
attr_reader :sort_keys
|
|
211
223
|
|
|
224
|
+
# Controls whether RFC8785 (canonicalization) mode is enabled. Otherwise returns false.
|
|
225
|
+
attr_writer :rfc8785
|
|
226
|
+
|
|
212
227
|
def sort_keys=(value) # :nodoc:
|
|
213
228
|
type_error = false
|
|
214
229
|
@sort_keys = case value
|
|
@@ -288,6 +303,27 @@ module JSON
|
|
|
288
303
|
@strict
|
|
289
304
|
end
|
|
290
305
|
|
|
306
|
+
# Returns true, if RFC8785 (canonicalization) mode is enabled. Otherwise returns false.
|
|
307
|
+
def rfc8785?
|
|
308
|
+
@rfc8785
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
def validate_rfc8785 # :nodoc:
|
|
312
|
+
if @rfc8785
|
|
313
|
+
option = if !@indent.empty? then :indent
|
|
314
|
+
elsif !@space.empty? then :space
|
|
315
|
+
elsif !@space_before.empty? then :space_before
|
|
316
|
+
elsif !@object_nl.empty? then :object_nl
|
|
317
|
+
elsif !@array_nl.empty? then :array_nl
|
|
318
|
+
elsif @ascii_only then :ascii_only
|
|
319
|
+
elsif @script_safe then :script_safe
|
|
320
|
+
elsif @allow_nan then :allow_nan
|
|
321
|
+
end
|
|
322
|
+
raise ArgumentError, "#{option} cannot be used with rfc8785" if option
|
|
323
|
+
end
|
|
324
|
+
self
|
|
325
|
+
end
|
|
326
|
+
|
|
291
327
|
# Configure this State instance with the Hash _opts_, and return
|
|
292
328
|
# itself.
|
|
293
329
|
def configure(options)
|
|
@@ -302,10 +338,13 @@ module JSON
|
|
|
302
338
|
end
|
|
303
339
|
alias merge configure
|
|
304
340
|
|
|
341
|
+
# Defaults are the current values so that #configure only writes what it was given.
|
|
305
342
|
private def _configure(
|
|
306
|
-
indent:
|
|
307
|
-
|
|
308
|
-
|
|
343
|
+
indent: @indent, space: @space, space_before: @space_before, object_nl: @object_nl,
|
|
344
|
+
array_nl: @array_nl, allow_nan: @allow_nan, as_json: @as_json, ascii_only: @ascii_only,
|
|
345
|
+
sort_keys: @sort_keys, depth: @depth, buffer_initial_length: @buffer_initial_length,
|
|
346
|
+
allow_duplicate_key: @allow_duplicate_key, script_safe: @script_safe, strict: @strict,
|
|
347
|
+
max_nesting: @max_nesting, rfc8785: @rfc8785
|
|
309
348
|
)
|
|
310
349
|
if depth.negative?
|
|
311
350
|
raise ArgumentError, "depth must be >= 0 (got #{depth})"
|
|
@@ -321,7 +360,11 @@ module JSON
|
|
|
321
360
|
@object_nl = object_nl || ''
|
|
322
361
|
@array_nl = array_nl || ''
|
|
323
362
|
@allow_nan = allow_nan || false
|
|
324
|
-
|
|
363
|
+
if as_json
|
|
364
|
+
self.as_json = as_json
|
|
365
|
+
else
|
|
366
|
+
@as_json = false
|
|
367
|
+
end
|
|
325
368
|
@ascii_only = ascii_only || false
|
|
326
369
|
self.sort_keys = sort_keys
|
|
327
370
|
@depth = depth
|
|
@@ -330,7 +373,9 @@ module JSON
|
|
|
330
373
|
@script_safe = script_safe
|
|
331
374
|
@strict = strict
|
|
332
375
|
@max_nesting = max_nesting || 0
|
|
333
|
-
self
|
|
376
|
+
self.rfc8785 = rfc8785
|
|
377
|
+
|
|
378
|
+
validate_rfc8785
|
|
334
379
|
end
|
|
335
380
|
|
|
336
381
|
def allow_duplicate_key? # :nodoc:
|
|
@@ -340,13 +385,24 @@ module JSON
|
|
|
340
385
|
# Returns the configuration instance variables as a hash, that can be
|
|
341
386
|
# passed to the configure method.
|
|
342
387
|
def to_h
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
388
|
+
{
|
|
389
|
+
indent: @indent,
|
|
390
|
+
space: @space,
|
|
391
|
+
space_before: @space_before,
|
|
392
|
+
object_nl: @object_nl,
|
|
393
|
+
array_nl: @array_nl,
|
|
394
|
+
as_json: @as_json,
|
|
395
|
+
allow_nan: @allow_nan,
|
|
396
|
+
ascii_only: @ascii_only,
|
|
397
|
+
max_nesting: @max_nesting,
|
|
398
|
+
script_safe: @script_safe,
|
|
399
|
+
strict: @strict,
|
|
400
|
+
depth: @depth,
|
|
401
|
+
buffer_initial_length: @buffer_initial_length,
|
|
402
|
+
sort_keys: @sort_keys,
|
|
403
|
+
allow_duplicate_key: @allow_duplicate_key,
|
|
404
|
+
rfc8785: @rfc8785,
|
|
405
|
+
}
|
|
350
406
|
end
|
|
351
407
|
|
|
352
408
|
alias to_hash to_h
|
|
@@ -359,16 +415,14 @@ module JSON
|
|
|
359
415
|
return dup.generate(obj, anIO) if frozen?
|
|
360
416
|
|
|
361
417
|
depth = @depth
|
|
418
|
+
validate_rfc8785
|
|
362
419
|
if @indent.empty? and @space.empty? and @space_before.empty? and @object_nl.empty? and @array_nl.empty? and
|
|
363
420
|
!@ascii_only and !@script_safe and @max_nesting == 0 and (!@strict || Symbol === obj) and !@sort_keys
|
|
364
421
|
result = generate_json(obj, ''.dup)
|
|
365
422
|
else
|
|
366
|
-
if @sort_keys
|
|
367
|
-
obj = @sort_keys.call(obj)
|
|
368
|
-
end
|
|
369
|
-
|
|
370
423
|
result = obj.to_json(self)
|
|
371
424
|
end
|
|
425
|
+
|
|
372
426
|
JSON::TruffleRuby::Generator.valid_utf8?(result) or raise GeneratorError.new(
|
|
373
427
|
"source sequence #{result.inspect} is illegal/malformed utf-8",
|
|
374
428
|
obj
|
|
@@ -390,6 +444,11 @@ module JSON
|
|
|
390
444
|
buf << '{'
|
|
391
445
|
first = true
|
|
392
446
|
key_type = nil
|
|
447
|
+
if @rfc8785
|
|
448
|
+
obj = State.rfc8785_sort_keys_proc.call(obj, @strict && @as_json)
|
|
449
|
+
elsif @sort_keys
|
|
450
|
+
obj = @sort_keys.call(obj)
|
|
451
|
+
end
|
|
393
452
|
obj.each_pair do |k,v|
|
|
394
453
|
if first
|
|
395
454
|
key_type = k.class
|
|
@@ -431,7 +490,7 @@ module JSON
|
|
|
431
490
|
buf << obj.to_json(self)
|
|
432
491
|
end
|
|
433
492
|
when Integer
|
|
434
|
-
buf << obj.to_s
|
|
493
|
+
buf << (@rfc8785 ? State.rfc8785_number_formatter_proc.call(obj) : obj.to_s)
|
|
435
494
|
when Symbol
|
|
436
495
|
if @strict
|
|
437
496
|
fast_serialize_string(obj.name, buf)
|
|
@@ -500,10 +559,12 @@ module JSON
|
|
|
500
559
|
def to_json(state = nil, *)
|
|
501
560
|
state = State.from_state(state)
|
|
502
561
|
depth = state.depth
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
562
|
+
begin
|
|
563
|
+
state.check_max_nesting
|
|
564
|
+
json_transform(state)
|
|
565
|
+
ensure
|
|
566
|
+
state.depth = depth
|
|
567
|
+
end
|
|
507
568
|
end
|
|
508
569
|
|
|
509
570
|
private
|
|
@@ -521,13 +582,21 @@ module JSON
|
|
|
521
582
|
first = true
|
|
522
583
|
key_type = nil
|
|
523
584
|
indent = !state.object_nl.empty?
|
|
524
|
-
|
|
585
|
+
hash = self
|
|
586
|
+
|
|
587
|
+
if state.rfc8785?
|
|
588
|
+
hash = State.rfc8785_sort_keys_proc.call(hash, state.strict? && state.as_json)
|
|
589
|
+
elsif state.sort_keys
|
|
590
|
+
hash = state.sort_keys.call(hash)
|
|
591
|
+
end
|
|
592
|
+
|
|
593
|
+
hash.each { |key, value|
|
|
525
594
|
if first
|
|
526
595
|
key_type = key.class
|
|
527
596
|
else
|
|
528
597
|
if key_type && !state.allow_duplicate_key? && key_type != key.class
|
|
529
598
|
key_type = nil # stop checking
|
|
530
|
-
JSON.send(:on_mixed_keys_hash,
|
|
599
|
+
JSON.send(:on_mixed_keys_hash, hash)
|
|
531
600
|
end
|
|
532
601
|
result << delim
|
|
533
602
|
end
|
|
@@ -592,10 +661,12 @@ module JSON
|
|
|
592
661
|
def to_json(state = nil, *)
|
|
593
662
|
state = State.from_state(state)
|
|
594
663
|
depth = state.depth
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
664
|
+
begin
|
|
665
|
+
state.check_max_nesting
|
|
666
|
+
json_transform(state)
|
|
667
|
+
ensure
|
|
668
|
+
state.depth = depth
|
|
669
|
+
end
|
|
599
670
|
end
|
|
600
671
|
|
|
601
672
|
private
|
|
@@ -648,13 +719,20 @@ module JSON
|
|
|
648
719
|
|
|
649
720
|
module Integer
|
|
650
721
|
# Returns a JSON string representation for this Integer number.
|
|
651
|
-
def to_json(*)
|
|
722
|
+
def to_json(state = nil, *)
|
|
723
|
+
if state && State.from_state(state).rfc8785?
|
|
724
|
+
State.rfc8785_number_formatter_proc.call(self)
|
|
725
|
+
else
|
|
726
|
+
to_s
|
|
727
|
+
end
|
|
728
|
+
end
|
|
652
729
|
end
|
|
653
730
|
|
|
654
731
|
module Float
|
|
655
732
|
# Returns a JSON string representation for this Float number.
|
|
656
733
|
def to_json(state = nil, *args)
|
|
657
734
|
state = State.from_state(state)
|
|
735
|
+
|
|
658
736
|
if infinite? || nan?
|
|
659
737
|
if state.allow_nan?
|
|
660
738
|
to_s
|
|
@@ -676,6 +754,8 @@ module JSON
|
|
|
676
754
|
else
|
|
677
755
|
raise GeneratorError.new("#{self} not allowed in JSON", self)
|
|
678
756
|
end
|
|
757
|
+
elsif state.rfc8785?
|
|
758
|
+
State.rfc8785_number_formatter_proc.call(self)
|
|
679
759
|
else
|
|
680
760
|
to_s
|
|
681
761
|
end
|
data/lib/json/version.rb
CHANGED
data/lib/json.rb
CHANGED
|
@@ -44,13 +44,13 @@ require 'json/common'
|
|
|
44
44
|
#
|
|
45
45
|
# You can parse a \String containing \JSON data using
|
|
46
46
|
# either of two methods:
|
|
47
|
-
# - <tt>JSON.parse(source, opts)</tt>
|
|
48
|
-
# - <tt>JSON.parse!(source, opts)</tt>
|
|
47
|
+
# - <tt>JSON.parse(source, **opts)</tt>
|
|
48
|
+
# - <tt>JSON.parse!(source, **opts)</tt>
|
|
49
49
|
#
|
|
50
50
|
# where
|
|
51
51
|
# - +source+ is a Ruby object.
|
|
52
|
-
# - +opts+
|
|
53
|
-
#
|
|
52
|
+
# - +opts+ are keyword arguments that control both input
|
|
53
|
+
# allowed and output formatting.
|
|
54
54
|
#
|
|
55
55
|
# The difference between the two methods
|
|
56
56
|
# is that JSON.parse! omits some checks
|
|
@@ -102,7 +102,7 @@ require 'json/common'
|
|
|
102
102
|
# ruby # => 1.0
|
|
103
103
|
# ruby.class # => Float
|
|
104
104
|
# ruby = JSON.parse('2.0e2')
|
|
105
|
-
# ruby # => 200
|
|
105
|
+
# ruby # => 200.0
|
|
106
106
|
# ruby.class # => Float
|
|
107
107
|
# Boolean:
|
|
108
108
|
# ruby = JSON.parse('true')
|
|
@@ -131,10 +131,10 @@ require 'json/common'
|
|
|
131
131
|
# ruby # => [0, [1, [2, [3]]]]
|
|
132
132
|
# Too deep:
|
|
133
133
|
# # Raises JSON::NestingError (nesting of 2 is too deep):
|
|
134
|
-
# JSON.parse(source,
|
|
134
|
+
# JSON.parse(source, max_nesting: 1)
|
|
135
135
|
# Bad value:
|
|
136
|
-
# # Raises TypeError (
|
|
137
|
-
# JSON.parse(source,
|
|
136
|
+
# # Raises TypeError (no implicit conversion of Symbol into Integer):
|
|
137
|
+
# JSON.parse(source, max_nesting: :foo)
|
|
138
138
|
#
|
|
139
139
|
# ---
|
|
140
140
|
#
|
|
@@ -142,11 +142,11 @@ require 'json/common'
|
|
|
142
142
|
# should be ignored or cause an error to be raised:
|
|
143
143
|
#
|
|
144
144
|
# When set to +false+, the default:
|
|
145
|
-
# JSON.parse('{"a": 1, "a":2}')
|
|
145
|
+
# JSON.parse('{"a": 1, "a": 2}') # duplicate key "a" at line 1 column 1 (JSON::ParserError)
|
|
146
146
|
#
|
|
147
147
|
# When set to +true+:
|
|
148
148
|
# # The last value is used.
|
|
149
|
-
# JSON.parse('{"a": 1, "a":2}', allow_duplicate_key: true) => {"a" => 2}
|
|
149
|
+
# JSON.parse('{"a": 1, "a": 2}', allow_duplicate_key: true) # => {"a" => 2}
|
|
150
150
|
#
|
|
151
151
|
# ---
|
|
152
152
|
#
|
|
@@ -155,15 +155,15 @@ require 'json/common'
|
|
|
155
155
|
# defaults to +false+.
|
|
156
156
|
#
|
|
157
157
|
# With the default, +false+:
|
|
158
|
-
# # Raises JSON::ParserError (
|
|
158
|
+
# # Raises JSON::ParserError (unexpected token 'NaN]' at line 1 column 2):
|
|
159
159
|
# JSON.parse('[NaN]')
|
|
160
|
-
# # Raises JSON::ParserError (
|
|
160
|
+
# # Raises JSON::ParserError (unexpected token 'Infinity]' at line 1 column 2):
|
|
161
161
|
# JSON.parse('[Infinity]')
|
|
162
|
-
# # Raises JSON::ParserError (
|
|
162
|
+
# # Raises JSON::ParserError (invalid number: '-Infinity]' at line 1 column 2):
|
|
163
163
|
# JSON.parse('[-Infinity]')
|
|
164
164
|
# Allow:
|
|
165
165
|
# source = '[NaN, Infinity, -Infinity]'
|
|
166
|
-
# ruby = JSON.parse(source,
|
|
166
|
+
# ruby = JSON.parse(source, allow_nan: true)
|
|
167
167
|
# ruby # => [NaN, Infinity, -Infinity]
|
|
168
168
|
#
|
|
169
169
|
# ---
|
|
@@ -185,10 +185,10 @@ require 'json/common'
|
|
|
185
185
|
# defaults to +false+.
|
|
186
186
|
#
|
|
187
187
|
# When set to +false+, the default:
|
|
188
|
-
# JSON.parse('/* comment */ {"a": 1, "a":2}') # unexpected
|
|
188
|
+
# JSON.parse('/* comment */ {"a": 1, "a": 2}') # unexpected token '/*' at line 1 column 1 (JSON::ParserError)
|
|
189
189
|
#
|
|
190
190
|
# When set to +true+, comments are ignored:
|
|
191
|
-
# JSON.parse('/* comment */ {"a": 1
|
|
191
|
+
# JSON.parse('/* comment */ {"a": 1} // more comment', allow_comments: true) # => {"a" => 1}
|
|
192
192
|
#
|
|
193
193
|
# ---
|
|
194
194
|
#
|
|
@@ -197,7 +197,7 @@ require 'json/common'
|
|
|
197
197
|
# defaults to +false+.
|
|
198
198
|
#
|
|
199
199
|
# With the default, +false+:
|
|
200
|
-
# JSON.parse(%{"Hello\nWorld"}) # invalid ASCII control character in string (JSON::ParserError)
|
|
200
|
+
# JSON.parse(%{"Hello\nWorld"}) # invalid ASCII control character in string: \nWorld" at line 2 column 0 (JSON::ParserError)
|
|
201
201
|
#
|
|
202
202
|
# When enabled:
|
|
203
203
|
# JSON.parse(%{"Hello\nWorld"}, allow_control_characters: true) # => "Hello\nWorld"
|
|
@@ -209,7 +209,7 @@ require 'json/common'
|
|
|
209
209
|
# defaults to +false+.
|
|
210
210
|
#
|
|
211
211
|
# With the default, +false+:
|
|
212
|
-
# JSON.parse('"Hell\o"') # invalid escape character in string (JSON::ParserError)
|
|
212
|
+
# JSON.parse('"Hell\o"') # invalid escape character in string: '\o"' at line 1 column 6 (JSON::ParserError)
|
|
213
213
|
#
|
|
214
214
|
# When enabled:
|
|
215
215
|
# JSON.parse('"Hell\o"', allow_invalid_escape: true) # => "Hello"
|
|
@@ -228,8 +228,8 @@ require 'json/common'
|
|
|
228
228
|
# ruby = JSON.parse(source)
|
|
229
229
|
# ruby # => {"a"=>"foo", "b"=>1.0, "c"=>true, "d"=>false, "e"=>nil}
|
|
230
230
|
# Use Symbols:
|
|
231
|
-
# ruby = JSON.parse(source,
|
|
232
|
-
# ruby # => {:
|
|
231
|
+
# ruby = JSON.parse(source, symbolize_names: true)
|
|
232
|
+
# ruby # => {a: "foo", b: 1.0, c: true, d: false, e: nil}
|
|
233
233
|
#
|
|
234
234
|
# ---
|
|
235
235
|
#
|
|
@@ -242,7 +242,7 @@ require 'json/common'
|
|
|
242
242
|
# ruby = JSON.parse(source)
|
|
243
243
|
# ruby.class # => Hash
|
|
244
244
|
# Use class \OpenStruct:
|
|
245
|
-
# ruby = JSON.parse(source,
|
|
245
|
+
# ruby = JSON.parse(source, object_class: OpenStruct)
|
|
246
246
|
# ruby # => #<OpenStruct a="foo", b=1.0, c=true, d=false, e=nil>
|
|
247
247
|
#
|
|
248
248
|
# ---
|
|
@@ -256,8 +256,8 @@ require 'json/common'
|
|
|
256
256
|
# ruby = JSON.parse(source)
|
|
257
257
|
# ruby.class # => Array
|
|
258
258
|
# Use class \Set:
|
|
259
|
-
# ruby = JSON.parse(source,
|
|
260
|
-
# ruby # =>
|
|
259
|
+
# ruby = JSON.parse(source, array_class: Set)
|
|
260
|
+
# ruby # => Set["foo", 1.0, true, false, nil]
|
|
261
261
|
#
|
|
262
262
|
# === Generating \JSON
|
|
263
263
|
#
|
|
@@ -319,22 +319,22 @@ require 'json/common'
|
|
|
319
319
|
# a \String containing a \JSON string representation of the source:
|
|
320
320
|
# JSON.generate(:foo) # => '"foo"'
|
|
321
321
|
# JSON.generate(Complex(0, 0)) # => '"0+0i"'
|
|
322
|
-
# JSON.generate(Dir.new('.')) # => '"#<Dir
|
|
322
|
+
# JSON.generate(Dir.new('.')) # => '"#<Dir:0x...>"'
|
|
323
323
|
#
|
|
324
324
|
# ==== Generating Options
|
|
325
325
|
#
|
|
326
326
|
# ====== Input Options
|
|
327
327
|
#
|
|
328
328
|
# Option +allow_nan+ (boolean) specifies whether
|
|
329
|
-
# +NaN+, +Infinity+, and
|
|
329
|
+
# +NaN+, +Infinity+, and +-Infinity+ may be generated;
|
|
330
330
|
# defaults to +false+.
|
|
331
331
|
#
|
|
332
332
|
# With the default, +false+:
|
|
333
|
-
# # Raises JSON::GeneratorError (
|
|
333
|
+
# # Raises JSON::GeneratorError (NaN not allowed in JSON):
|
|
334
334
|
# JSON.generate(JSON::NaN)
|
|
335
|
-
# # Raises JSON::GeneratorError (
|
|
335
|
+
# # Raises JSON::GeneratorError (Infinity not allowed in JSON):
|
|
336
336
|
# JSON.generate(JSON::Infinity)
|
|
337
|
-
# # Raises JSON::GeneratorError (
|
|
337
|
+
# # Raises JSON::GeneratorError (-Infinity not allowed in JSON):
|
|
338
338
|
# JSON.generate(JSON::MinusInfinity)
|
|
339
339
|
#
|
|
340
340
|
# Allow:
|
|
@@ -345,14 +345,14 @@ require 'json/common'
|
|
|
345
345
|
#
|
|
346
346
|
# Option +allow_duplicate_key+ (boolean) specifies whether
|
|
347
347
|
# hashes with duplicate keys should be allowed or produce an error.
|
|
348
|
-
#
|
|
348
|
+
# Defaults to +false+, which raises an error.
|
|
349
349
|
#
|
|
350
|
-
# With the default,
|
|
351
|
-
# JSON.generate({
|
|
350
|
+
# With the default, +false+:
|
|
351
|
+
# JSON.generate({foo: 1, "foo" => 2})
|
|
352
352
|
# # detected duplicate key "foo" in {foo: 1, "foo" => 2} (JSON::GeneratorError)
|
|
353
353
|
#
|
|
354
|
-
# With
|
|
355
|
-
# JSON.generate({
|
|
354
|
+
# With +true+:
|
|
355
|
+
# JSON.generate({foo: 1, "foo" => 2}, allow_duplicate_key: true)
|
|
356
356
|
# # => '{"foo":1,"foo":2}'
|
|
357
357
|
#
|
|
358
358
|
# ---
|
|
@@ -365,13 +365,13 @@ require 'json/common'
|
|
|
365
365
|
# JSON.generate(obj) # => '[[[[[[0]]]]]]'
|
|
366
366
|
#
|
|
367
367
|
# Too deep:
|
|
368
|
-
# # Raises JSON::NestingError (nesting of 2 is too deep):
|
|
368
|
+
# # Raises JSON::NestingError (nesting of 2 is too deep. Did you try to serialize objects with circular references?):
|
|
369
369
|
# JSON.generate(obj, max_nesting: 2)
|
|
370
370
|
#
|
|
371
371
|
# With +false+:
|
|
372
372
|
# obj = []
|
|
373
373
|
# obj[0] = obj
|
|
374
|
-
# # Raises
|
|
374
|
+
# # Raises SystemStackError (stack level too deep):
|
|
375
375
|
# JSON.generate(obj, max_nesting: false)
|
|
376
376
|
#
|
|
377
377
|
# Setting +max_nesting+ to +false+ or a very large number can lead to a stack overflow
|
|
@@ -410,10 +410,18 @@ require 'json/common'
|
|
|
410
410
|
# inserted before the colon in each \JSON object's pair;
|
|
411
411
|
# defaults to the empty \String, <tt>''</tt>.
|
|
412
412
|
# - Option +sort_keys+ (boolean or \Proc) controls whether and how the keys of a
|
|
413
|
-
# hash are sorted when generating the output; defaults to
|
|
413
|
+
# hash are sorted when generating the output; defaults to +false+.
|
|
414
414
|
# When +true+, keys are sorted lexicographically. When a \Proc, it receives
|
|
415
415
|
# the entire \Hash and must return a \Hash with its pairs in the desired
|
|
416
416
|
# order, allowing for arbitrary sort orders.
|
|
417
|
+
# - Option +rfc8785+ (boolean) controls whether the generated JSON will be canonicalized
|
|
418
|
+
# as defined in RFC8785.
|
|
419
|
+
# Integers are converted to Float before formatting and may be rounded.
|
|
420
|
+
# Integers outside the finite Float range raise JSON::GeneratorError.
|
|
421
|
+
# Nonempty +indent+, +space+, +space_before+, +object_nl+, or +array_nl+,
|
|
422
|
+
# and enabled +ascii_only+, +script_safe+, or +allow_nan+ raise ArgumentError.
|
|
423
|
+
# JSON.dump defaults +allow_nan+ to +false+ when +rfc8785+ is enabled.
|
|
424
|
+
# JSON::Fragment contents are inserted as is; the caller must ensure they are canonical.
|
|
417
425
|
#
|
|
418
426
|
# In this example, +obj+ is used first to generate the shortest
|
|
419
427
|
# \JSON data (no whitespace), then again with all formatting options
|
|
@@ -439,7 +447,7 @@ require 'json/common'
|
|
|
439
447
|
# "foo" : [
|
|
440
448
|
# "bar",
|
|
441
449
|
# "baz"
|
|
442
|
-
#
|
|
450
|
+
# ],
|
|
443
451
|
# "bat" : {
|
|
444
452
|
# "bam" : 0,
|
|
445
453
|
# "bad" : 1
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: json
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.0
|
|
4
|
+
version: 3.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Florian Frank
|
|
@@ -68,7 +68,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
68
68
|
- !ruby/object:Gem::Version
|
|
69
69
|
version: '0'
|
|
70
70
|
requirements: []
|
|
71
|
-
rubygems_version: 4.0.
|
|
71
|
+
rubygems_version: 4.0.20
|
|
72
72
|
specification_version: 4
|
|
73
73
|
summary: JSON Implementation for Ruby
|
|
74
74
|
test_files: []
|