json 2.10.2 → 2.15.1
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 +110 -7
- data/README.md +16 -1
- data/ext/json/ext/fbuffer/fbuffer.h +110 -19
- data/ext/json/ext/generator/extconf.rb +6 -0
- data/ext/json/ext/generator/generator.c +543 -196
- data/ext/json/ext/parser/extconf.rb +5 -2
- data/ext/json/ext/parser/parser.c +339 -268
- data/ext/json/ext/simd/conf.rb +24 -0
- data/ext/json/ext/simd/simd.h +188 -0
- data/ext/json/ext/vendor/fpconv.c +480 -0
- data/ext/json/ext/vendor/jeaiii-ltoa.h +267 -0
- data/json.gemspec +2 -3
- data/lib/json/add/core.rb +1 -0
- data/lib/json/add/string.rb +35 -0
- data/lib/json/common.rb +312 -169
- data/lib/json/ext/generator/state.rb +7 -14
- data/lib/json/ext.rb +2 -2
- data/lib/json/generic_object.rb +0 -8
- data/lib/json/truffle_ruby/generator.rb +64 -46
- data/lib/json/version.rb +1 -1
- data/lib/json.rb +55 -0
- metadata +8 -3
data/lib/json/common.rb
CHANGED
|
@@ -5,10 +5,114 @@ require 'json/version'
|
|
|
5
5
|
module JSON
|
|
6
6
|
autoload :GenericObject, 'json/generic_object'
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
module ParserOptions # :nodoc:
|
|
9
|
+
class << self
|
|
10
|
+
def prepare(opts)
|
|
11
|
+
if opts[:object_class] || opts[:array_class]
|
|
12
|
+
opts = opts.dup
|
|
13
|
+
on_load = opts[:on_load]
|
|
14
|
+
|
|
15
|
+
on_load = object_class_proc(opts[:object_class], on_load) if opts[:object_class]
|
|
16
|
+
on_load = array_class_proc(opts[:array_class], on_load) if opts[:array_class]
|
|
17
|
+
opts[:on_load] = on_load
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
if opts.fetch(:create_additions, false) != false
|
|
21
|
+
opts = create_additions_proc(opts)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
opts
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def object_class_proc(object_class, on_load)
|
|
30
|
+
->(obj) do
|
|
31
|
+
if Hash === obj
|
|
32
|
+
object = object_class.new
|
|
33
|
+
obj.each { |k, v| object[k] = v }
|
|
34
|
+
obj = object
|
|
35
|
+
end
|
|
36
|
+
on_load.nil? ? obj : on_load.call(obj)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def array_class_proc(array_class, on_load)
|
|
41
|
+
->(obj) do
|
|
42
|
+
if Array === obj
|
|
43
|
+
array = array_class.new
|
|
44
|
+
obj.each { |v| array << v }
|
|
45
|
+
obj = array
|
|
46
|
+
end
|
|
47
|
+
on_load.nil? ? obj : on_load.call(obj)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# TODO: extract :create_additions support to another gem for version 3.0
|
|
52
|
+
def create_additions_proc(opts)
|
|
53
|
+
if opts[:symbolize_names]
|
|
54
|
+
raise ArgumentError, "options :symbolize_names and :create_additions cannot be used in conjunction"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
opts = opts.dup
|
|
58
|
+
create_additions = opts.fetch(:create_additions, false)
|
|
59
|
+
on_load = opts[:on_load]
|
|
60
|
+
object_class = opts[:object_class] || Hash
|
|
61
|
+
|
|
62
|
+
opts[:on_load] = ->(object) do
|
|
63
|
+
case object
|
|
64
|
+
when String
|
|
65
|
+
opts[:match_string]&.each do |pattern, klass|
|
|
66
|
+
if match = pattern.match(object)
|
|
67
|
+
create_additions_warning if create_additions.nil?
|
|
68
|
+
object = klass.json_create(object)
|
|
69
|
+
break
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
when object_class
|
|
73
|
+
if opts[:create_additions] != false
|
|
74
|
+
if class_name = object[JSON.create_id]
|
|
75
|
+
klass = JSON.deep_const_get(class_name)
|
|
76
|
+
if klass.respond_to?(:json_creatable?) ? klass.json_creatable? : klass.respond_to?(:json_create)
|
|
77
|
+
create_additions_warning if create_additions.nil?
|
|
78
|
+
object = klass.json_create(object)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
on_load.nil? ? object : on_load.call(object)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
opts
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def create_additions_warning
|
|
91
|
+
JSON.deprecation_warning "JSON.load implicit support for `create_additions: true` is deprecated " \
|
|
92
|
+
"and will be removed in 3.0, use JSON.unsafe_load or explicitly " \
|
|
93
|
+
"pass `create_additions: true`"
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
10
97
|
|
|
11
98
|
class << self
|
|
99
|
+
def deprecation_warning(message, uplevel = 3) # :nodoc:
|
|
100
|
+
gem_root = File.expand_path("..", __dir__) + "/"
|
|
101
|
+
caller_locations(uplevel, 10).each do |frame|
|
|
102
|
+
if frame.path.nil? || frame.path.start_with?(gem_root) || frame.path.end_with?("/truffle/cext_ruby.rb", ".c")
|
|
103
|
+
uplevel += 1
|
|
104
|
+
else
|
|
105
|
+
break
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
if RUBY_VERSION >= "3.0"
|
|
110
|
+
warn(message, uplevel: uplevel, category: :deprecated)
|
|
111
|
+
else
|
|
112
|
+
warn(message, uplevel: uplevel)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
12
116
|
# :call-seq:
|
|
13
117
|
# JSON[object] -> new_array or new_string
|
|
14
118
|
#
|
|
@@ -20,7 +124,7 @@ module JSON
|
|
|
20
124
|
# Otherwise, calls JSON.generate with +object+ and +opts+ (see method #generate):
|
|
21
125
|
# ruby = [0, 1, nil]
|
|
22
126
|
# JSON[ruby] # => '[0,1,null]'
|
|
23
|
-
def [](object, opts =
|
|
127
|
+
def [](object, opts = nil)
|
|
24
128
|
if object.is_a?(String)
|
|
25
129
|
return JSON.parse(object, opts)
|
|
26
130
|
elsif object.respond_to?(:to_str)
|
|
@@ -69,38 +173,58 @@ module JSON
|
|
|
69
173
|
end
|
|
70
174
|
end
|
|
71
175
|
self.state = generator::State
|
|
72
|
-
const_set :State,
|
|
73
|
-
const_set :SAFE_STATE_PROTOTYPE, State.new # for JRuby
|
|
74
|
-
const_set :FAST_STATE_PROTOTYPE, create_fast_state
|
|
75
|
-
const_set :PRETTY_STATE_PROTOTYPE, create_pretty_state
|
|
176
|
+
const_set :State, state
|
|
76
177
|
ensure
|
|
77
178
|
$VERBOSE = old
|
|
78
179
|
end
|
|
79
180
|
|
|
80
|
-
def create_fast_state
|
|
81
|
-
State.new(
|
|
82
|
-
:indent => '',
|
|
83
|
-
:space => '',
|
|
84
|
-
:object_nl => "",
|
|
85
|
-
:array_nl => "",
|
|
86
|
-
:max_nesting => false
|
|
87
|
-
)
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
def create_pretty_state
|
|
91
|
-
State.new(
|
|
92
|
-
:indent => ' ',
|
|
93
|
-
:space => ' ',
|
|
94
|
-
:object_nl => "\n",
|
|
95
|
-
:array_nl => "\n"
|
|
96
|
-
)
|
|
97
|
-
end
|
|
98
|
-
|
|
99
181
|
# Returns the JSON generator module that is used by JSON.
|
|
100
182
|
attr_reader :generator
|
|
101
183
|
|
|
102
184
|
# Sets or Returns the JSON generator state class that is used by JSON.
|
|
103
185
|
attr_accessor :state
|
|
186
|
+
|
|
187
|
+
private
|
|
188
|
+
|
|
189
|
+
# Called from the extension when a hash has both string and symbol keys
|
|
190
|
+
def on_mixed_keys_hash(hash, do_raise)
|
|
191
|
+
set = {}
|
|
192
|
+
hash.each_key do |key|
|
|
193
|
+
key_str = key.to_s
|
|
194
|
+
|
|
195
|
+
if set[key_str]
|
|
196
|
+
message = "detected duplicate key #{key_str.inspect} in #{hash.inspect}"
|
|
197
|
+
if do_raise
|
|
198
|
+
raise GeneratorError, message
|
|
199
|
+
else
|
|
200
|
+
deprecation_warning("#{message}.\nThis will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`")
|
|
201
|
+
end
|
|
202
|
+
else
|
|
203
|
+
set[key_str] = true
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def deprecated_singleton_attr_accessor(*attrs)
|
|
209
|
+
args = RUBY_VERSION >= "3.0" ? ", category: :deprecated" : ""
|
|
210
|
+
attrs.each do |attr|
|
|
211
|
+
singleton_class.class_eval <<~RUBY
|
|
212
|
+
def #{attr}
|
|
213
|
+
warn "JSON.#{attr} is deprecated and will be removed in json 3.0.0", uplevel: 1 #{args}
|
|
214
|
+
@#{attr}
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def #{attr}=(val)
|
|
218
|
+
warn "JSON.#{attr}= is deprecated and will be removed in json 3.0.0", uplevel: 1 #{args}
|
|
219
|
+
@#{attr} = val
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def _#{attr}
|
|
223
|
+
@#{attr}
|
|
224
|
+
end
|
|
225
|
+
RUBY
|
|
226
|
+
end
|
|
227
|
+
end
|
|
104
228
|
end
|
|
105
229
|
|
|
106
230
|
# Sets create identifier, which is used to decide if the _json_create_
|
|
@@ -116,32 +240,24 @@ module JSON
|
|
|
116
240
|
Thread.current[:"JSON.create_id"] || 'json_class'
|
|
117
241
|
end
|
|
118
242
|
|
|
119
|
-
NaN =
|
|
243
|
+
NaN = Float::NAN
|
|
120
244
|
|
|
121
|
-
Infinity =
|
|
245
|
+
Infinity = Float::INFINITY
|
|
122
246
|
|
|
123
247
|
MinusInfinity = -Infinity
|
|
124
248
|
|
|
125
249
|
# The base exception for JSON errors.
|
|
126
|
-
class JSONError < StandardError
|
|
127
|
-
def self.wrap(exception)
|
|
128
|
-
obj = new("Wrapped(#{exception.class}): #{exception.message.inspect}")
|
|
129
|
-
obj.set_backtrace exception.backtrace
|
|
130
|
-
obj
|
|
131
|
-
end
|
|
132
|
-
end
|
|
250
|
+
class JSONError < StandardError; end
|
|
133
251
|
|
|
134
252
|
# This exception is raised if a parser error occurs.
|
|
135
|
-
class ParserError < JSONError
|
|
253
|
+
class ParserError < JSONError
|
|
254
|
+
attr_reader :line, :column
|
|
255
|
+
end
|
|
136
256
|
|
|
137
257
|
# This exception is raised if the nesting of parsed data structures is too
|
|
138
258
|
# deep.
|
|
139
259
|
class NestingError < ParserError; end
|
|
140
260
|
|
|
141
|
-
# :stopdoc:
|
|
142
|
-
class CircularDatastructure < NestingError; end
|
|
143
|
-
# :startdoc:
|
|
144
|
-
|
|
145
261
|
# This exception is raised if a generator or unparser error occurs.
|
|
146
262
|
class GeneratorError < JSONError
|
|
147
263
|
attr_reader :invalid_object
|
|
@@ -163,13 +279,6 @@ module JSON
|
|
|
163
279
|
end
|
|
164
280
|
end
|
|
165
281
|
|
|
166
|
-
# For backwards compatibility
|
|
167
|
-
UnparserError = GeneratorError # :nodoc:
|
|
168
|
-
|
|
169
|
-
# This exception is raised if the required unicode support is missing on the
|
|
170
|
-
# system. Usually this means that the iconv library is not installed.
|
|
171
|
-
class MissingUnicodeSupport < JSONError; end
|
|
172
|
-
|
|
173
282
|
# Fragment of JSON document that is to be included as is:
|
|
174
283
|
# fragment = JSON::Fragment.new("[1, 2, 3]")
|
|
175
284
|
# JSON.generate({ count: 3, items: fragments })
|
|
@@ -179,7 +288,7 @@ module JSON
|
|
|
179
288
|
# to string interpolation.
|
|
180
289
|
#
|
|
181
290
|
# Note: no validation is performed on the provided string. It is the
|
|
182
|
-
#
|
|
291
|
+
# responsibility of the caller to ensure the string contains valid JSON.
|
|
183
292
|
Fragment = Struct.new(:json) do
|
|
184
293
|
def initialize(json)
|
|
185
294
|
unless string = String.try_convert(json)
|
|
@@ -245,9 +354,16 @@ module JSON
|
|
|
245
354
|
# JSON.parse('')
|
|
246
355
|
#
|
|
247
356
|
def parse(source, opts = nil)
|
|
357
|
+
opts = ParserOptions.prepare(opts) unless opts.nil?
|
|
248
358
|
Parser.parse(source, opts)
|
|
249
359
|
end
|
|
250
360
|
|
|
361
|
+
PARSE_L_OPTIONS = {
|
|
362
|
+
max_nesting: false,
|
|
363
|
+
allow_nan: true,
|
|
364
|
+
}.freeze
|
|
365
|
+
private_constant :PARSE_L_OPTIONS
|
|
366
|
+
|
|
251
367
|
# :call-seq:
|
|
252
368
|
# JSON.parse!(source, opts) -> object
|
|
253
369
|
#
|
|
@@ -260,12 +376,11 @@ module JSON
|
|
|
260
376
|
# which disables checking for nesting depth.
|
|
261
377
|
# - Option +allow_nan+, if not provided, defaults to +true+.
|
|
262
378
|
def parse!(source, opts = nil)
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
Parser.new(source, options).parse
|
|
379
|
+
if opts.nil?
|
|
380
|
+
parse(source, PARSE_L_OPTIONS)
|
|
381
|
+
else
|
|
382
|
+
parse(source, PARSE_L_OPTIONS.merge(opts))
|
|
383
|
+
end
|
|
269
384
|
end
|
|
270
385
|
|
|
271
386
|
# :call-seq:
|
|
@@ -295,7 +410,7 @@ module JSON
|
|
|
295
410
|
#
|
|
296
411
|
# Returns a \String containing the generated \JSON data.
|
|
297
412
|
#
|
|
298
|
-
# See also JSON.
|
|
413
|
+
# See also JSON.pretty_generate.
|
|
299
414
|
#
|
|
300
415
|
# Argument +obj+ is the Ruby object to be converted to \JSON.
|
|
301
416
|
#
|
|
@@ -334,13 +449,6 @@ module JSON
|
|
|
334
449
|
end
|
|
335
450
|
end
|
|
336
451
|
|
|
337
|
-
# :stopdoc:
|
|
338
|
-
# I want to deprecate these later, so I'll first be silent about them, and
|
|
339
|
-
# later delete them.
|
|
340
|
-
alias unparse generate
|
|
341
|
-
module_function :unparse
|
|
342
|
-
# :startdoc:
|
|
343
|
-
|
|
344
452
|
# :call-seq:
|
|
345
453
|
# JSON.fast_generate(obj, opts) -> new_string
|
|
346
454
|
#
|
|
@@ -355,19 +463,21 @@ module JSON
|
|
|
355
463
|
# # Raises SystemStackError (stack level too deep):
|
|
356
464
|
# JSON.fast_generate(a)
|
|
357
465
|
def fast_generate(obj, opts = nil)
|
|
358
|
-
if
|
|
359
|
-
|
|
466
|
+
if RUBY_VERSION >= "3.0"
|
|
467
|
+
warn "JSON.fast_generate is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1, category: :deprecated
|
|
360
468
|
else
|
|
361
|
-
|
|
469
|
+
warn "JSON.fast_generate is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1
|
|
362
470
|
end
|
|
363
|
-
|
|
471
|
+
generate(obj, opts)
|
|
364
472
|
end
|
|
365
473
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
474
|
+
PRETTY_GENERATE_OPTIONS = {
|
|
475
|
+
indent: ' ',
|
|
476
|
+
space: ' ',
|
|
477
|
+
object_nl: "\n",
|
|
478
|
+
array_nl: "\n",
|
|
479
|
+
}.freeze
|
|
480
|
+
private_constant :PRETTY_GENERATE_OPTIONS
|
|
371
481
|
|
|
372
482
|
# :call-seq:
|
|
373
483
|
# JSON.pretty_generate(obj, opts = nil) -> new_string
|
|
@@ -400,52 +510,46 @@ module JSON
|
|
|
400
510
|
# }
|
|
401
511
|
#
|
|
402
512
|
def pretty_generate(obj, opts = nil)
|
|
403
|
-
if State === opts
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
end
|
|
513
|
+
return opts.generate(obj) if State === opts
|
|
514
|
+
|
|
515
|
+
options = PRETTY_GENERATE_OPTIONS
|
|
516
|
+
|
|
408
517
|
if opts
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
518
|
+
unless opts.is_a?(Hash)
|
|
519
|
+
if opts.respond_to? :to_hash
|
|
520
|
+
opts = opts.to_hash
|
|
521
|
+
elsif opts.respond_to? :to_h
|
|
522
|
+
opts = opts.to_h
|
|
523
|
+
else
|
|
524
|
+
raise TypeError, "can't convert #{opts.class} into Hash"
|
|
525
|
+
end
|
|
415
526
|
end
|
|
416
|
-
|
|
527
|
+
options = options.merge(opts)
|
|
417
528
|
end
|
|
418
|
-
|
|
529
|
+
|
|
530
|
+
State.generate(obj, options, nil)
|
|
419
531
|
end
|
|
420
532
|
|
|
421
|
-
#
|
|
422
|
-
#
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
533
|
+
# Sets or returns default options for the JSON.unsafe_load method.
|
|
534
|
+
# Initially:
|
|
535
|
+
# opts = JSON.load_default_options
|
|
536
|
+
# opts # => {:max_nesting=>false, :allow_nan=>true, :allow_blank=>true, :create_additions=>true}
|
|
537
|
+
deprecated_singleton_attr_accessor :unsafe_load_default_options
|
|
426
538
|
|
|
427
|
-
|
|
428
|
-
# Sets or returns default options for the JSON.unsafe_load method.
|
|
429
|
-
# Initially:
|
|
430
|
-
# opts = JSON.load_default_options
|
|
431
|
-
# opts # => {:max_nesting=>false, :allow_nan=>true, :allow_blank=>true, :create_additions=>true}
|
|
432
|
-
attr_accessor :unsafe_load_default_options
|
|
433
|
-
end
|
|
434
|
-
self.unsafe_load_default_options = {
|
|
539
|
+
@unsafe_load_default_options = {
|
|
435
540
|
:max_nesting => false,
|
|
436
541
|
:allow_nan => true,
|
|
437
542
|
:allow_blank => true,
|
|
438
543
|
:create_additions => true,
|
|
439
544
|
}
|
|
440
545
|
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
self.load_default_options = {
|
|
546
|
+
# Sets or returns default options for the JSON.load method.
|
|
547
|
+
# Initially:
|
|
548
|
+
# opts = JSON.load_default_options
|
|
549
|
+
# opts # => {:max_nesting=>false, :allow_nan=>true, :allow_blank=>true, :create_additions=>true}
|
|
550
|
+
deprecated_singleton_attr_accessor :load_default_options
|
|
551
|
+
|
|
552
|
+
@load_default_options = {
|
|
449
553
|
:allow_nan => true,
|
|
450
554
|
:allow_blank => true,
|
|
451
555
|
:create_additions => nil,
|
|
@@ -558,6 +662,7 @@ module JSON
|
|
|
558
662
|
# when Array
|
|
559
663
|
# obj.map! {|v| deserialize_obj v }
|
|
560
664
|
# end
|
|
665
|
+
# obj
|
|
561
666
|
# })
|
|
562
667
|
# pp ruby
|
|
563
668
|
# Output:
|
|
@@ -581,9 +686,9 @@ module JSON
|
|
|
581
686
|
#
|
|
582
687
|
def unsafe_load(source, proc = nil, options = nil)
|
|
583
688
|
opts = if options.nil?
|
|
584
|
-
|
|
689
|
+
_unsafe_load_default_options
|
|
585
690
|
else
|
|
586
|
-
|
|
691
|
+
_unsafe_load_default_options.merge(options)
|
|
587
692
|
end
|
|
588
693
|
|
|
589
694
|
unless source.is_a?(String)
|
|
@@ -599,9 +704,13 @@ module JSON
|
|
|
599
704
|
if opts[:allow_blank] && (source.nil? || source.empty?)
|
|
600
705
|
source = 'null'
|
|
601
706
|
end
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
707
|
+
|
|
708
|
+
if proc
|
|
709
|
+
opts = opts.dup
|
|
710
|
+
opts[:on_load] = proc.to_proc
|
|
711
|
+
end
|
|
712
|
+
|
|
713
|
+
parse(source, opts)
|
|
605
714
|
end
|
|
606
715
|
|
|
607
716
|
# :call-seq:
|
|
@@ -718,6 +827,7 @@ module JSON
|
|
|
718
827
|
# when Array
|
|
719
828
|
# obj.map! {|v| deserialize_obj v }
|
|
720
829
|
# end
|
|
830
|
+
# obj
|
|
721
831
|
# })
|
|
722
832
|
# pp ruby
|
|
723
833
|
# Output:
|
|
@@ -741,9 +851,9 @@ module JSON
|
|
|
741
851
|
#
|
|
742
852
|
def load(source, proc = nil, options = nil)
|
|
743
853
|
opts = if options.nil?
|
|
744
|
-
|
|
854
|
+
_load_default_options
|
|
745
855
|
else
|
|
746
|
-
|
|
856
|
+
_load_default_options.merge(options)
|
|
747
857
|
end
|
|
748
858
|
|
|
749
859
|
unless source.is_a?(String)
|
|
@@ -759,36 +869,21 @@ module JSON
|
|
|
759
869
|
if opts[:allow_blank] && (source.nil? || source.empty?)
|
|
760
870
|
source = 'null'
|
|
761
871
|
end
|
|
762
|
-
result = parse(source, opts)
|
|
763
|
-
recurse_proc(result, &proc) if proc
|
|
764
|
-
result
|
|
765
|
-
end
|
|
766
872
|
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
when Array
|
|
771
|
-
result.each { |x| recurse_proc x, &proc }
|
|
772
|
-
proc.call result
|
|
773
|
-
when Hash
|
|
774
|
-
result.each { |x, y| recurse_proc x, &proc; recurse_proc y, &proc }
|
|
775
|
-
proc.call result
|
|
776
|
-
else
|
|
777
|
-
proc.call result
|
|
873
|
+
if proc
|
|
874
|
+
opts = opts.dup
|
|
875
|
+
opts[:on_load] = proc.to_proc
|
|
778
876
|
end
|
|
779
|
-
end
|
|
780
|
-
|
|
781
|
-
alias restore load
|
|
782
|
-
module_function :restore
|
|
783
877
|
|
|
784
|
-
|
|
785
|
-
# Sets or returns the default options for the JSON.dump method.
|
|
786
|
-
# Initially:
|
|
787
|
-
# opts = JSON.dump_default_options
|
|
788
|
-
# opts # => {:max_nesting=>false, :allow_nan=>true}
|
|
789
|
-
attr_accessor :dump_default_options
|
|
878
|
+
parse(source, opts)
|
|
790
879
|
end
|
|
791
|
-
|
|
880
|
+
|
|
881
|
+
# Sets or returns the default options for the JSON.dump method.
|
|
882
|
+
# Initially:
|
|
883
|
+
# opts = JSON.dump_default_options
|
|
884
|
+
# opts # => {:max_nesting=>false, :allow_nan=>true}
|
|
885
|
+
deprecated_singleton_attr_accessor :dump_default_options
|
|
886
|
+
@dump_default_options = {
|
|
792
887
|
:max_nesting => false,
|
|
793
888
|
:allow_nan => true,
|
|
794
889
|
}
|
|
@@ -841,7 +936,7 @@ module JSON
|
|
|
841
936
|
end
|
|
842
937
|
end
|
|
843
938
|
|
|
844
|
-
opts = JSON.
|
|
939
|
+
opts = JSON._dump_default_options
|
|
845
940
|
opts = opts.merge(:max_nesting => limit) if limit
|
|
846
941
|
opts = opts.merge(kwargs) if kwargs
|
|
847
942
|
|
|
@@ -852,10 +947,67 @@ module JSON
|
|
|
852
947
|
end
|
|
853
948
|
end
|
|
854
949
|
|
|
855
|
-
#
|
|
856
|
-
|
|
857
|
-
|
|
950
|
+
# :stopdoc:
|
|
951
|
+
# All these were meant to be deprecated circa 2009, but were just set as undocumented
|
|
952
|
+
# so usage still exist in the wild.
|
|
953
|
+
def unparse(...)
|
|
954
|
+
if RUBY_VERSION >= "3.0"
|
|
955
|
+
warn "JSON.unparse is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1, category: :deprecated
|
|
956
|
+
else
|
|
957
|
+
warn "JSON.unparse is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1
|
|
958
|
+
end
|
|
959
|
+
generate(...)
|
|
858
960
|
end
|
|
961
|
+
module_function :unparse
|
|
962
|
+
|
|
963
|
+
def fast_unparse(...)
|
|
964
|
+
if RUBY_VERSION >= "3.0"
|
|
965
|
+
warn "JSON.fast_unparse is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1, category: :deprecated
|
|
966
|
+
else
|
|
967
|
+
warn "JSON.fast_unparse is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1
|
|
968
|
+
end
|
|
969
|
+
generate(...)
|
|
970
|
+
end
|
|
971
|
+
module_function :fast_unparse
|
|
972
|
+
|
|
973
|
+
def pretty_unparse(...)
|
|
974
|
+
if RUBY_VERSION >= "3.0"
|
|
975
|
+
warn "JSON.pretty_unparse is deprecated and will be removed in json 3.0.0, just use JSON.pretty_generate", uplevel: 1, category: :deprecated
|
|
976
|
+
else
|
|
977
|
+
warn "JSON.pretty_unparse is deprecated and will be removed in json 3.0.0, just use JSON.pretty_generate", uplevel: 1
|
|
978
|
+
end
|
|
979
|
+
pretty_generate(...)
|
|
980
|
+
end
|
|
981
|
+
module_function :fast_unparse
|
|
982
|
+
|
|
983
|
+
def restore(...)
|
|
984
|
+
if RUBY_VERSION >= "3.0"
|
|
985
|
+
warn "JSON.restore is deprecated and will be removed in json 3.0.0, just use JSON.load", uplevel: 1, category: :deprecated
|
|
986
|
+
else
|
|
987
|
+
warn "JSON.restore is deprecated and will be removed in json 3.0.0, just use JSON.load", uplevel: 1
|
|
988
|
+
end
|
|
989
|
+
load(...)
|
|
990
|
+
end
|
|
991
|
+
module_function :restore
|
|
992
|
+
|
|
993
|
+
class << self
|
|
994
|
+
private
|
|
995
|
+
|
|
996
|
+
def const_missing(const_name)
|
|
997
|
+
case const_name
|
|
998
|
+
when :PRETTY_STATE_PROTOTYPE
|
|
999
|
+
if RUBY_VERSION >= "3.0"
|
|
1000
|
+
warn "JSON::PRETTY_STATE_PROTOTYPE is deprecated and will be removed in json 3.0.0, just use JSON.pretty_generate", uplevel: 1, category: :deprecated
|
|
1001
|
+
else
|
|
1002
|
+
warn "JSON::PRETTY_STATE_PROTOTYPE is deprecated and will be removed in json 3.0.0, just use JSON.pretty_generate", uplevel: 1
|
|
1003
|
+
end
|
|
1004
|
+
state.new(PRETTY_GENERATE_OPTIONS)
|
|
1005
|
+
else
|
|
1006
|
+
super
|
|
1007
|
+
end
|
|
1008
|
+
end
|
|
1009
|
+
end
|
|
1010
|
+
# :startdoc:
|
|
859
1011
|
|
|
860
1012
|
# JSON::Coder holds a parser and generator configuration.
|
|
861
1013
|
#
|
|
@@ -875,7 +1027,7 @@ module JSON
|
|
|
875
1027
|
# See {Parsing Options}[#module-JSON-label-Parsing+Options], and {Generating Options}[#module-JSON-label-Generating+Options].
|
|
876
1028
|
#
|
|
877
1029
|
# For generation, the <tt>strict: true</tt> option is always set. When a Ruby object with no native \JSON counterpart is
|
|
878
|
-
#
|
|
1030
|
+
# encountered, the block provided to the initialize method is invoked, and must return a Ruby object that has a native
|
|
879
1031
|
# \JSON counterpart:
|
|
880
1032
|
#
|
|
881
1033
|
# module MyApp
|
|
@@ -899,10 +1051,9 @@ module JSON
|
|
|
899
1051
|
options[:strict] = true
|
|
900
1052
|
end
|
|
901
1053
|
options[:as_json] = as_json if as_json
|
|
902
|
-
options[:create_additions] = false unless options.key?(:create_additions)
|
|
903
1054
|
|
|
904
1055
|
@state = State.new(options).freeze
|
|
905
|
-
@parser_config = Ext::Parser::Config.new(options)
|
|
1056
|
+
@parser_config = Ext::Parser::Config.new(ParserOptions.prepare(options))
|
|
906
1057
|
end
|
|
907
1058
|
|
|
908
1059
|
# call-seq:
|
|
@@ -940,8 +1091,14 @@ module ::Kernel
|
|
|
940
1091
|
# Outputs _objs_ to STDOUT as JSON strings in the shortest form, that is in
|
|
941
1092
|
# one line.
|
|
942
1093
|
def j(*objs)
|
|
1094
|
+
if RUBY_VERSION >= "3.0"
|
|
1095
|
+
warn "Kernel#j is deprecated and will be removed in json 3.0.0", uplevel: 1, category: :deprecated
|
|
1096
|
+
else
|
|
1097
|
+
warn "Kernel#j is deprecated and will be removed in json 3.0.0", uplevel: 1
|
|
1098
|
+
end
|
|
1099
|
+
|
|
943
1100
|
objs.each do |obj|
|
|
944
|
-
puts JSON
|
|
1101
|
+
puts JSON.generate(obj, :allow_nan => true, :max_nesting => false)
|
|
945
1102
|
end
|
|
946
1103
|
nil
|
|
947
1104
|
end
|
|
@@ -949,8 +1106,14 @@ module ::Kernel
|
|
|
949
1106
|
# Outputs _objs_ to STDOUT as JSON strings in a pretty format, with
|
|
950
1107
|
# indentation and over many lines.
|
|
951
1108
|
def jj(*objs)
|
|
1109
|
+
if RUBY_VERSION >= "3.0"
|
|
1110
|
+
warn "Kernel#jj is deprecated and will be removed in json 3.0.0", uplevel: 1, category: :deprecated
|
|
1111
|
+
else
|
|
1112
|
+
warn "Kernel#jj is deprecated and will be removed in json 3.0.0", uplevel: 1
|
|
1113
|
+
end
|
|
1114
|
+
|
|
952
1115
|
objs.each do |obj|
|
|
953
|
-
puts JSON
|
|
1116
|
+
puts JSON.pretty_generate(obj, :allow_nan => true, :max_nesting => false)
|
|
954
1117
|
end
|
|
955
1118
|
nil
|
|
956
1119
|
end
|
|
@@ -961,27 +1124,7 @@ module ::Kernel
|
|
|
961
1124
|
#
|
|
962
1125
|
# The _opts_ argument is passed through to generate/parse respectively. See
|
|
963
1126
|
# generate and parse for their documentation.
|
|
964
|
-
def JSON(object,
|
|
965
|
-
|
|
966
|
-
return JSON.parse(object, args.first)
|
|
967
|
-
elsif object.respond_to?(:to_str)
|
|
968
|
-
str = object.to_str
|
|
969
|
-
if str.is_a?(String)
|
|
970
|
-
return JSON.parse(object.to_str, args.first)
|
|
971
|
-
end
|
|
972
|
-
end
|
|
973
|
-
|
|
974
|
-
JSON.generate(object, args.first)
|
|
975
|
-
end
|
|
976
|
-
end
|
|
977
|
-
|
|
978
|
-
# Extends any Class to include _json_creatable?_ method.
|
|
979
|
-
class ::Class
|
|
980
|
-
# Returns true if this class can be used to create an instance
|
|
981
|
-
# from a serialised JSON string. The class has to implement a class
|
|
982
|
-
# method _json_create_ that expects a hash as first parameter. The hash
|
|
983
|
-
# should include the required data.
|
|
984
|
-
def json_creatable?
|
|
985
|
-
respond_to?(:json_create)
|
|
1127
|
+
def JSON(object, opts = nil)
|
|
1128
|
+
JSON[object, opts]
|
|
986
1129
|
end
|
|
987
1130
|
end
|