json 2.21.1-java → 3.0.0.rc1-java
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 +45 -0
- data/README.md +4 -84
- data/lib/json/common.rb +86 -402
- data/lib/json/ext/generator/state.rb +0 -27
- data/lib/json/ext/generator.jar +0 -0
- data/lib/json/ext/parser.jar +0 -0
- data/lib/json/ext.rb +0 -2
- data/lib/json/truffle_ruby/generator.rb +38 -80
- data/lib/json/version.rb +1 -1
- data/lib/json.rb +24 -265
- metadata +2 -18
- data/lib/json/add/bigdecimal.rb +0 -58
- data/lib/json/add/complex.rb +0 -51
- data/lib/json/add/core.rb +0 -13
- data/lib/json/add/date.rb +0 -54
- data/lib/json/add/date_time.rb +0 -67
- data/lib/json/add/exception.rb +0 -49
- data/lib/json/add/ostruct.rb +0 -54
- data/lib/json/add/range.rb +0 -54
- data/lib/json/add/rational.rb +0 -49
- data/lib/json/add/regexp.rb +0 -48
- data/lib/json/add/set.rb +0 -48
- data/lib/json/add/string.rb +0 -35
- data/lib/json/add/struct.rb +0 -52
- data/lib/json/add/symbol.rb +0 -52
- data/lib/json/add/time.rb +0 -52
- data/lib/json/generic_object.rb +0 -67
data/lib/json/common.rb
CHANGED
|
@@ -3,25 +3,12 @@
|
|
|
3
3
|
require 'json/version'
|
|
4
4
|
|
|
5
5
|
module JSON
|
|
6
|
-
autoload :GenericObject, 'json/generic_object'
|
|
7
|
-
|
|
8
6
|
module ParserOptions # :nodoc:
|
|
9
7
|
class << self
|
|
10
|
-
def
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
|
8
|
+
def on_load(on_load, object_class, array_class)
|
|
9
|
+
on_load = object_class_proc(object_class, on_load) if object_class
|
|
10
|
+
on_load = array_class_proc(array_class, on_load) if array_class
|
|
11
|
+
on_load
|
|
25
12
|
end
|
|
26
13
|
|
|
27
14
|
private
|
|
@@ -47,77 +34,12 @@ module JSON
|
|
|
47
34
|
on_load.nil? ? obj : on_load.call(obj)
|
|
48
35
|
end
|
|
49
36
|
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_path = object[JSON.create_id]
|
|
75
|
-
klass = begin
|
|
76
|
-
Object.const_get(class_path)
|
|
77
|
-
rescue NameError => e
|
|
78
|
-
raise ArgumentError, "can't get const #{class_path}: #{e}"
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
if klass.respond_to?(:json_creatable?) ? klass.json_creatable? : klass.respond_to?(:json_create)
|
|
82
|
-
create_additions_warning if create_additions.nil?
|
|
83
|
-
object = klass.json_create(object)
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
on_load.nil? ? object : on_load.call(object)
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
opts
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
def create_additions_warning
|
|
96
|
-
JSON.deprecation_warning "JSON.load implicit support for `create_additions: true` is deprecated " \
|
|
97
|
-
"and will be removed in 3.0, use JSON.unsafe_load or explicitly " \
|
|
98
|
-
"pass `create_additions: true`"
|
|
99
|
-
end
|
|
100
37
|
end
|
|
101
38
|
end
|
|
102
39
|
|
|
103
|
-
|
|
104
|
-
def deprecation_warning(message, uplevel = 3) # :nodoc:
|
|
105
|
-
gem_root = File.expand_path("..", __dir__) + "/"
|
|
106
|
-
caller_locations(uplevel, 10).each do |frame|
|
|
107
|
-
if frame.path.nil? || frame.path.start_with?(gem_root) || frame.path.end_with?("/truffle/cext_ruby.rb", ".c")
|
|
108
|
-
uplevel += 1
|
|
109
|
-
else
|
|
110
|
-
break
|
|
111
|
-
end
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
if RUBY_VERSION >= "3.0"
|
|
115
|
-
warn(message, uplevel: uplevel, category: :deprecated)
|
|
116
|
-
else
|
|
117
|
-
warn(message, uplevel: uplevel)
|
|
118
|
-
end
|
|
119
|
-
end
|
|
40
|
+
private_constant :ParserOptions
|
|
120
41
|
|
|
42
|
+
class << self
|
|
121
43
|
# :call-seq:
|
|
122
44
|
# JSON[object] -> new_array or new_string
|
|
123
45
|
#
|
|
@@ -130,12 +52,14 @@ module JSON
|
|
|
130
52
|
# ruby = [0, 1, nil]
|
|
131
53
|
# JSON[ruby] # => '[0,1,null]'
|
|
132
54
|
def [](object, opts = nil)
|
|
55
|
+
opts ||= {}.freeze
|
|
56
|
+
|
|
133
57
|
if object.is_a?(String)
|
|
134
|
-
return JSON.parse(object, opts)
|
|
58
|
+
return JSON.parse(object, **opts)
|
|
135
59
|
elsif object.respond_to?(:to_str)
|
|
136
60
|
str = object.to_str
|
|
137
61
|
if str.is_a?(String)
|
|
138
|
-
return JSON.parse(str, opts)
|
|
62
|
+
return JSON.parse(str, **opts)
|
|
139
63
|
end
|
|
140
64
|
end
|
|
141
65
|
|
|
@@ -193,57 +117,18 @@ module JSON
|
|
|
193
117
|
private
|
|
194
118
|
|
|
195
119
|
# Called from the extension when a hash has both string and symbol keys
|
|
196
|
-
def on_mixed_keys_hash(hash
|
|
120
|
+
def on_mixed_keys_hash(hash)
|
|
197
121
|
set = {}
|
|
198
122
|
hash.each_key do |key|
|
|
199
123
|
key_str = key.to_s
|
|
200
124
|
|
|
201
125
|
if set[key_str]
|
|
202
|
-
|
|
203
|
-
if do_raise
|
|
204
|
-
raise GeneratorError, message
|
|
205
|
-
else
|
|
206
|
-
deprecation_warning("#{message}.\nThis will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`")
|
|
207
|
-
end
|
|
126
|
+
raise GeneratorError, "detected duplicate key #{key_str.inspect} in #{hash.inspect}"
|
|
208
127
|
else
|
|
209
128
|
set[key_str] = true
|
|
210
129
|
end
|
|
211
130
|
end
|
|
212
131
|
end
|
|
213
|
-
|
|
214
|
-
def deprecated_singleton_attr_accessor(*attrs)
|
|
215
|
-
args = RUBY_VERSION >= "3.0" ? ", category: :deprecated" : ""
|
|
216
|
-
attrs.each do |attr|
|
|
217
|
-
singleton_class.class_eval <<~RUBY
|
|
218
|
-
def #{attr}
|
|
219
|
-
warn "JSON.#{attr} is deprecated and will be removed in json 3.0.0", uplevel: 1 #{args}
|
|
220
|
-
@#{attr}
|
|
221
|
-
end
|
|
222
|
-
|
|
223
|
-
def #{attr}=(val)
|
|
224
|
-
warn "JSON.#{attr}= is deprecated and will be removed in json 3.0.0", uplevel: 1 #{args}
|
|
225
|
-
@#{attr} = val
|
|
226
|
-
end
|
|
227
|
-
|
|
228
|
-
def _#{attr}
|
|
229
|
-
@#{attr}
|
|
230
|
-
end
|
|
231
|
-
RUBY
|
|
232
|
-
end
|
|
233
|
-
end
|
|
234
|
-
end
|
|
235
|
-
|
|
236
|
-
# Sets create identifier, which is used to decide if the _json_create_
|
|
237
|
-
# hook of a class should be called; initial value is +json_class+:
|
|
238
|
-
# JSON.create_id # => 'json_class'
|
|
239
|
-
def self.create_id=(new_value)
|
|
240
|
-
Thread.current[:"JSON.create_id"] = new_value.dup.freeze
|
|
241
|
-
end
|
|
242
|
-
|
|
243
|
-
# Returns the current create identifier.
|
|
244
|
-
# See also JSON.create_id=.
|
|
245
|
-
def self.create_id
|
|
246
|
-
Thread.current[:"JSON.create_id"] || 'json_class'
|
|
247
132
|
end
|
|
248
133
|
|
|
249
134
|
NaN = Float::NAN
|
|
@@ -356,19 +241,17 @@ module JSON
|
|
|
356
241
|
# ---
|
|
357
242
|
#
|
|
358
243
|
# Raises an exception if +source+ is not valid JSON:
|
|
359
|
-
# # Raises JSON::ParserError
|
|
360
|
-
# JSON.parse('')
|
|
244
|
+
# # Raises JSON::ParserError unexpected character: 'invalid' at line 1 column 1 :
|
|
245
|
+
# JSON.parse('invalid')
|
|
361
246
|
#
|
|
362
|
-
def parse(source,
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
247
|
+
def parse(source, on_load: nil, object_class: nil, array_class: nil, **options)
|
|
248
|
+
if object_class || array_class
|
|
249
|
+
on_load = ParserOptions.on_load(on_load, object_class, array_class)
|
|
250
|
+
end
|
|
366
251
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
}.freeze
|
|
371
|
-
private_constant :PARSE_L_OPTIONS
|
|
252
|
+
options[:on_load] = on_load if on_load
|
|
253
|
+
Parser.parse(source, options)
|
|
254
|
+
end
|
|
372
255
|
|
|
373
256
|
# :call-seq:
|
|
374
257
|
# JSON.parse!(source, opts) -> object
|
|
@@ -381,34 +264,30 @@ module JSON
|
|
|
381
264
|
# - Option +max_nesting+, if not provided, defaults to +false+,
|
|
382
265
|
# which disables checking for nesting depth.
|
|
383
266
|
# - Option +allow_nan+, if not provided, defaults to +true+.
|
|
384
|
-
def parse!(source,
|
|
385
|
-
|
|
386
|
-
parse(source, PARSE_L_OPTIONS)
|
|
387
|
-
else
|
|
388
|
-
parse(source, PARSE_L_OPTIONS.merge(opts))
|
|
389
|
-
end
|
|
267
|
+
def parse!(source, **options)
|
|
268
|
+
parse(source, max_nesting: false, allow_nan: true, **options)
|
|
390
269
|
end
|
|
391
270
|
|
|
392
271
|
# :call-seq:
|
|
393
|
-
# JSON.load_file(path,
|
|
272
|
+
# JSON.load_file(path, **) -> object
|
|
394
273
|
#
|
|
395
274
|
# Calls:
|
|
396
|
-
# parse(File.read(path),
|
|
275
|
+
# parse(File.read(path), **)
|
|
397
276
|
#
|
|
398
277
|
# See method #parse.
|
|
399
|
-
def load_file(filespec,
|
|
400
|
-
parse(File.read(filespec, encoding: Encoding::UTF_8),
|
|
278
|
+
def load_file(filespec, ...)
|
|
279
|
+
parse(File.read(filespec, encoding: Encoding::UTF_8), ...)
|
|
401
280
|
end
|
|
402
281
|
|
|
403
282
|
# :call-seq:
|
|
404
|
-
# JSON.load_file!(path,
|
|
283
|
+
# JSON.load_file!(path, **)
|
|
405
284
|
#
|
|
406
285
|
# Calls:
|
|
407
|
-
# JSON.parse!(File.read(path,
|
|
286
|
+
# JSON.parse!(File.read(path), **)
|
|
408
287
|
#
|
|
409
288
|
# See method #parse!
|
|
410
|
-
def load_file!(filespec,
|
|
411
|
-
parse!(File.read(filespec, encoding: Encoding::UTF_8),
|
|
289
|
+
def load_file!(filespec, ...)
|
|
290
|
+
parse!(File.read(filespec, encoding: Encoding::UTF_8), ...)
|
|
412
291
|
end
|
|
413
292
|
|
|
414
293
|
# :call-seq:
|
|
@@ -451,30 +330,8 @@ module JSON
|
|
|
451
330
|
if State === opts
|
|
452
331
|
opts.generate(obj)
|
|
453
332
|
else
|
|
454
|
-
State.generate(obj, opts, nil)
|
|
455
|
-
end
|
|
456
|
-
end
|
|
457
|
-
|
|
458
|
-
# :call-seq:
|
|
459
|
-
# JSON.fast_generate(obj, opts) -> new_string
|
|
460
|
-
#
|
|
461
|
-
# Arguments +obj+ and +opts+ here are the same as
|
|
462
|
-
# arguments +obj+ and +opts+ in JSON.generate.
|
|
463
|
-
#
|
|
464
|
-
# By default, generates \JSON data without checking
|
|
465
|
-
# for circular references in +obj+ (option +max_nesting+ set to +false+, disabled).
|
|
466
|
-
#
|
|
467
|
-
# Raises an exception if +obj+ contains circular references:
|
|
468
|
-
# a = []; b = []; a.push(b); b.push(a)
|
|
469
|
-
# # Raises SystemStackError (stack level too deep):
|
|
470
|
-
# JSON.fast_generate(a)
|
|
471
|
-
def fast_generate(obj, opts = nil)
|
|
472
|
-
if RUBY_VERSION >= "3.0"
|
|
473
|
-
warn "JSON.fast_generate is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1, category: :deprecated
|
|
474
|
-
else
|
|
475
|
-
warn "JSON.fast_generate is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1
|
|
333
|
+
State.generate(obj, opts.frozen? ? opts : opts.dup, nil)
|
|
476
334
|
end
|
|
477
|
-
generate(obj, opts)
|
|
478
335
|
end
|
|
479
336
|
|
|
480
337
|
PRETTY_GENERATE_OPTIONS = {
|
|
@@ -530,43 +387,20 @@ module JSON
|
|
|
530
387
|
raise TypeError, "can't convert #{opts.class} into Hash"
|
|
531
388
|
end
|
|
532
389
|
end
|
|
390
|
+
|
|
533
391
|
options = options.merge(opts)
|
|
534
392
|
end
|
|
535
393
|
|
|
536
394
|
State.generate(obj, options, nil)
|
|
537
395
|
end
|
|
538
396
|
|
|
539
|
-
# Sets or returns default options for the JSON.unsafe_load method.
|
|
540
|
-
# Initially:
|
|
541
|
-
# opts = JSON.load_default_options
|
|
542
|
-
# opts # => {:max_nesting=>false, :allow_nan=>true, :allow_blank=>true, :create_additions=>true}
|
|
543
|
-
deprecated_singleton_attr_accessor :unsafe_load_default_options
|
|
544
|
-
|
|
545
|
-
@unsafe_load_default_options = {
|
|
546
|
-
:max_nesting => false,
|
|
547
|
-
:allow_nan => true,
|
|
548
|
-
:allow_blank => true,
|
|
549
|
-
:create_additions => true,
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
# Sets or returns default options for the JSON.load method.
|
|
553
|
-
# Initially:
|
|
554
|
-
# opts = JSON.load_default_options
|
|
555
|
-
# opts # => {:max_nesting=>false, :allow_nan=>true, :allow_blank=>true, :create_additions=>true}
|
|
556
|
-
deprecated_singleton_attr_accessor :load_default_options
|
|
557
|
-
|
|
558
|
-
@load_default_options = {
|
|
559
|
-
:allow_nan => true,
|
|
560
|
-
:allow_blank => true,
|
|
561
|
-
:create_additions => nil,
|
|
562
|
-
}
|
|
563
397
|
# :call-seq:
|
|
564
398
|
# JSON.unsafe_load(source, options = {}) -> object
|
|
565
399
|
# JSON.unsafe_load(source, proc = nil, options = {}) -> object
|
|
566
400
|
#
|
|
567
401
|
# Returns the Ruby objects created by parsing the given +source+.
|
|
568
402
|
#
|
|
569
|
-
# BEWARE: This method is meant to
|
|
403
|
+
# BEWARE: This method is meant to deserialise data from trusted user input,
|
|
570
404
|
# like from your own database server or clients under your control, it could
|
|
571
405
|
# be dangerous to allow untrusted users to pass JSON sources into it.
|
|
572
406
|
#
|
|
@@ -586,7 +420,6 @@ module JSON
|
|
|
586
420
|
# See details below.
|
|
587
421
|
# - Argument +opts+, if given, contains a \Hash of options for the parsing.
|
|
588
422
|
# See {Parsing Options}[#module-JSON-label-Parsing+Options].
|
|
589
|
-
# The default options can be changed via method JSON.unsafe_load_default_options=.
|
|
590
423
|
#
|
|
591
424
|
# ---
|
|
592
425
|
#
|
|
@@ -691,38 +524,8 @@ module JSON
|
|
|
691
524
|
# #<Admin:0x00000000064c41f8
|
|
692
525
|
# @attributes={"type"=>"Admin", "password"=>"0wn3d"}>}
|
|
693
526
|
#
|
|
694
|
-
def unsafe_load(source, proc = nil, options
|
|
695
|
-
|
|
696
|
-
if proc && proc.is_a?(Hash)
|
|
697
|
-
options, proc = proc, nil
|
|
698
|
-
options
|
|
699
|
-
else
|
|
700
|
-
_unsafe_load_default_options
|
|
701
|
-
end
|
|
702
|
-
else
|
|
703
|
-
_unsafe_load_default_options.merge(options)
|
|
704
|
-
end
|
|
705
|
-
|
|
706
|
-
unless source.is_a?(String)
|
|
707
|
-
if source.respond_to? :to_str
|
|
708
|
-
source = source.to_str
|
|
709
|
-
elsif source.respond_to? :to_io
|
|
710
|
-
source = source.to_io.read
|
|
711
|
-
elsif source.respond_to?(:read)
|
|
712
|
-
source = source.read
|
|
713
|
-
end
|
|
714
|
-
end
|
|
715
|
-
|
|
716
|
-
if opts[:allow_blank] && (source.nil? || source.empty?)
|
|
717
|
-
source = 'null'
|
|
718
|
-
end
|
|
719
|
-
|
|
720
|
-
if proc
|
|
721
|
-
opts = opts.dup
|
|
722
|
-
opts[:on_load] = proc.to_proc
|
|
723
|
-
end
|
|
724
|
-
|
|
725
|
-
parse(source, opts)
|
|
527
|
+
def unsafe_load(source, proc = nil, **options)
|
|
528
|
+
load(source, proc, max_nesting: false, **options)
|
|
726
529
|
end
|
|
727
530
|
|
|
728
531
|
# :call-seq:
|
|
@@ -731,16 +534,6 @@ module JSON
|
|
|
731
534
|
#
|
|
732
535
|
# Returns the Ruby objects created by parsing the given +source+.
|
|
733
536
|
#
|
|
734
|
-
# BEWARE: This method is meant to serialise data from trusted user input,
|
|
735
|
-
# like from your own database server or clients under your control, it could
|
|
736
|
-
# be dangerous to allow untrusted users to pass JSON sources into it.
|
|
737
|
-
# If you must use it, use JSON.unsafe_load instead to make it clear.
|
|
738
|
-
#
|
|
739
|
-
# Since JSON version 2.8.0, `load` emits a deprecation warning when a
|
|
740
|
-
# non native type is deserialized, without `create_additions` being explicitly
|
|
741
|
-
# enabled, and in JSON version 3.0, `load` will have `create_additions` disabled
|
|
742
|
-
# by default.
|
|
743
|
-
#
|
|
744
537
|
# - Argument +source+ must be, or be convertible to, a \String:
|
|
745
538
|
# - If +source+ responds to instance method +to_str+,
|
|
746
539
|
# <tt>source.to_str</tt> becomes the source.
|
|
@@ -757,7 +550,6 @@ module JSON
|
|
|
757
550
|
# See details below.
|
|
758
551
|
# - Argument +opts+, if given, contains a \Hash of options for the parsing.
|
|
759
552
|
# See {Parsing Options}[#module-JSON-label-Parsing+Options].
|
|
760
|
-
# The default options can be changed via method JSON.load_default_options=.
|
|
761
553
|
#
|
|
762
554
|
# ---
|
|
763
555
|
#
|
|
@@ -862,23 +654,7 @@ module JSON
|
|
|
862
654
|
# #<Admin:0x00000000064c41f8
|
|
863
655
|
# @attributes={"type"=>"Admin", "password"=>"0wn3d"}>}
|
|
864
656
|
#
|
|
865
|
-
def load(source, proc = nil,
|
|
866
|
-
if proc && options.nil? && proc.is_a?(Hash)
|
|
867
|
-
options = proc
|
|
868
|
-
proc = nil
|
|
869
|
-
end
|
|
870
|
-
|
|
871
|
-
opts = if options.nil?
|
|
872
|
-
if proc && proc.is_a?(Hash)
|
|
873
|
-
options, proc = proc, nil
|
|
874
|
-
options
|
|
875
|
-
else
|
|
876
|
-
_load_default_options
|
|
877
|
-
end
|
|
878
|
-
else
|
|
879
|
-
_load_default_options.merge(options)
|
|
880
|
-
end
|
|
881
|
-
|
|
657
|
+
def load(source, proc = nil, allow_blank: true, **options)
|
|
882
658
|
unless source.is_a?(String)
|
|
883
659
|
if source.respond_to? :to_str
|
|
884
660
|
source = source.to_str
|
|
@@ -889,30 +665,19 @@ module JSON
|
|
|
889
665
|
end
|
|
890
666
|
end
|
|
891
667
|
|
|
892
|
-
if
|
|
668
|
+
if allow_blank && (source.nil? || (String === source && source.empty?))
|
|
893
669
|
source = 'null'
|
|
894
670
|
end
|
|
895
671
|
|
|
896
672
|
if proc
|
|
897
|
-
|
|
898
|
-
|
|
673
|
+
parse(source, allow_nan: true, on_load: proc.to_proc, **options)
|
|
674
|
+
else
|
|
675
|
+
parse(source, allow_nan: true, **options)
|
|
899
676
|
end
|
|
900
|
-
|
|
901
|
-
parse(source, opts)
|
|
902
677
|
end
|
|
903
678
|
|
|
904
|
-
# Sets or returns the default options for the JSON.dump method.
|
|
905
|
-
# Initially:
|
|
906
|
-
# opts = JSON.dump_default_options
|
|
907
|
-
# opts # => {:max_nesting=>false, :allow_nan=>true}
|
|
908
|
-
deprecated_singleton_attr_accessor :dump_default_options
|
|
909
|
-
@dump_default_options = {
|
|
910
|
-
:max_nesting => false,
|
|
911
|
-
:allow_nan => true,
|
|
912
|
-
}
|
|
913
|
-
|
|
914
679
|
# :call-seq:
|
|
915
|
-
# JSON.dump(obj, io = nil,
|
|
680
|
+
# JSON.dump(obj, io = nil, options = nil)
|
|
916
681
|
#
|
|
917
682
|
# Dumps +obj+ as a \JSON string, i.e. calls generate on the object and returns the result.
|
|
918
683
|
#
|
|
@@ -921,7 +686,6 @@ module JSON
|
|
|
921
686
|
# - Argument +io+, if given, should respond to method +write+;
|
|
922
687
|
# the \JSON \String is written to +io+, and +io+ is returned.
|
|
923
688
|
# If +io+ is not given, the \JSON \String is returned.
|
|
924
|
-
# - Argument +limit+, if given, is passed to JSON.generate as option +max_nesting+.
|
|
925
689
|
#
|
|
926
690
|
# ---
|
|
927
691
|
#
|
|
@@ -938,99 +702,25 @@ module JSON
|
|
|
938
702
|
# puts File.read(path)
|
|
939
703
|
# Output:
|
|
940
704
|
# {"foo":[0,1],"bar":{"baz":2,"bat":3},"bam":"bad"}
|
|
941
|
-
def dump(obj, anIO = nil,
|
|
705
|
+
def dump(obj, anIO = nil, kwargs = nil)
|
|
942
706
|
if kwargs.nil?
|
|
943
|
-
if
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
anIO = nil
|
|
947
|
-
end
|
|
948
|
-
elsif limit.is_a?(Hash)
|
|
949
|
-
kwargs = limit
|
|
950
|
-
limit = nil
|
|
707
|
+
if anIO.is_a?(Hash)
|
|
708
|
+
kwargs = anIO
|
|
709
|
+
anIO = nil
|
|
951
710
|
end
|
|
952
711
|
end
|
|
953
712
|
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
anIO = anIO.to_io
|
|
957
|
-
elsif limit.nil? && !anIO.respond_to?(:write)
|
|
958
|
-
anIO, limit = nil, anIO
|
|
959
|
-
end
|
|
960
|
-
end
|
|
961
|
-
|
|
962
|
-
opts = JSON._dump_default_options
|
|
963
|
-
opts = opts.merge(:max_nesting => limit) if limit
|
|
964
|
-
opts = opts.merge(kwargs) if kwargs
|
|
965
|
-
|
|
966
|
-
begin
|
|
967
|
-
State.generate(obj, opts, anIO)
|
|
968
|
-
rescue JSON::NestingError
|
|
969
|
-
raise ArgumentError, "exceed depth limit"
|
|
970
|
-
end
|
|
971
|
-
end
|
|
972
|
-
|
|
973
|
-
# :stopdoc:
|
|
974
|
-
# All these were meant to be deprecated circa 2009, but were just set as undocumented
|
|
975
|
-
# so usage still exist in the wild.
|
|
976
|
-
def unparse(...)
|
|
977
|
-
if RUBY_VERSION >= "3.0"
|
|
978
|
-
warn "JSON.unparse is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1, category: :deprecated
|
|
979
|
-
else
|
|
980
|
-
warn "JSON.unparse is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1
|
|
981
|
-
end
|
|
982
|
-
generate(...)
|
|
983
|
-
end
|
|
984
|
-
module_function :unparse
|
|
985
|
-
|
|
986
|
-
def fast_unparse(...)
|
|
987
|
-
if RUBY_VERSION >= "3.0"
|
|
988
|
-
warn "JSON.fast_unparse is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1, category: :deprecated
|
|
989
|
-
else
|
|
990
|
-
warn "JSON.fast_unparse is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1
|
|
713
|
+
if anIO&.respond_to?(:to_io)
|
|
714
|
+
anIO = anIO.to_io
|
|
991
715
|
end
|
|
992
|
-
generate(...)
|
|
993
|
-
end
|
|
994
|
-
module_function :fast_unparse
|
|
995
716
|
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
warn "JSON.pretty_unparse is deprecated and will be removed in json 3.0.0, just use JSON.pretty_generate", uplevel: 1
|
|
1001
|
-
end
|
|
1002
|
-
pretty_generate(...)
|
|
1003
|
-
end
|
|
1004
|
-
module_function :fast_unparse
|
|
717
|
+
opts = {
|
|
718
|
+
allow_nan: true,
|
|
719
|
+
}
|
|
720
|
+
opts.merge!(kwargs) if kwargs
|
|
1005
721
|
|
|
1006
|
-
|
|
1007
|
-
if RUBY_VERSION >= "3.0"
|
|
1008
|
-
warn "JSON.restore is deprecated and will be removed in json 3.0.0, just use JSON.load", uplevel: 1, category: :deprecated
|
|
1009
|
-
else
|
|
1010
|
-
warn "JSON.restore is deprecated and will be removed in json 3.0.0, just use JSON.load", uplevel: 1
|
|
1011
|
-
end
|
|
1012
|
-
load(...)
|
|
1013
|
-
end
|
|
1014
|
-
module_function :restore
|
|
1015
|
-
|
|
1016
|
-
class << self
|
|
1017
|
-
private
|
|
1018
|
-
|
|
1019
|
-
def const_missing(const_name)
|
|
1020
|
-
case const_name
|
|
1021
|
-
when :PRETTY_STATE_PROTOTYPE
|
|
1022
|
-
if RUBY_VERSION >= "3.0"
|
|
1023
|
-
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
|
|
1024
|
-
else
|
|
1025
|
-
warn "JSON::PRETTY_STATE_PROTOTYPE is deprecated and will be removed in json 3.0.0, just use JSON.pretty_generate", uplevel: 1
|
|
1026
|
-
end
|
|
1027
|
-
state.new(PRETTY_GENERATE_OPTIONS)
|
|
1028
|
-
else
|
|
1029
|
-
super
|
|
1030
|
-
end
|
|
1031
|
-
end
|
|
722
|
+
State.generate(obj, opts, anIO)
|
|
1032
723
|
end
|
|
1033
|
-
# :startdoc:
|
|
1034
724
|
|
|
1035
725
|
# JSON::Coder holds a parser and generator configuration.
|
|
1036
726
|
#
|
|
@@ -1043,6 +733,27 @@ module JSON
|
|
|
1043
733
|
# MyApp::JSONC_CODER.load(document)
|
|
1044
734
|
#
|
|
1045
735
|
class Coder
|
|
736
|
+
PARSER_OPTIONS = %i(
|
|
737
|
+
max_nesting
|
|
738
|
+
allow_nan
|
|
739
|
+
allow_trailing_comma
|
|
740
|
+
allow_comments
|
|
741
|
+
allow_control_characters
|
|
742
|
+
allow_invalid_escape
|
|
743
|
+
symbolize_names
|
|
744
|
+
freeze
|
|
745
|
+
allow_duplicate_key
|
|
746
|
+
decimal_class
|
|
747
|
+
).freeze
|
|
748
|
+
private_constant :PARSER_OPTIONS
|
|
749
|
+
|
|
750
|
+
EXCLUDED_GENERATOR_OPTIONS = (PARSER_OPTIONS - %i(
|
|
751
|
+
max_nesting
|
|
752
|
+
allow_nan
|
|
753
|
+
allow_duplicate_key
|
|
754
|
+
)).freeze
|
|
755
|
+
private_constant :EXCLUDED_GENERATOR_OPTIONS
|
|
756
|
+
|
|
1046
757
|
# :call-seq:
|
|
1047
758
|
# JSON.new(options = nil, &block)
|
|
1048
759
|
#
|
|
@@ -1067,17 +778,20 @@ module JSON
|
|
|
1067
778
|
#
|
|
1068
779
|
# puts MyApp::API_JSON_CODER.dump(Time.now.utc) # => "2025-01-21T08:41:44.286Z"
|
|
1069
780
|
#
|
|
1070
|
-
def initialize(
|
|
1071
|
-
if
|
|
1072
|
-
|
|
1073
|
-
else
|
|
1074
|
-
options = options.dup
|
|
1075
|
-
options[:strict] = true
|
|
781
|
+
def initialize(object_class: nil, array_class: nil, on_load: nil, **options, &as_json)
|
|
782
|
+
if object_class || array_class
|
|
783
|
+
on_load = ParserOptions.on_load(on_load, object_class, array_class)
|
|
1076
784
|
end
|
|
1077
|
-
|
|
785
|
+
parser_options = options.slice(*PARSER_OPTIONS)
|
|
786
|
+
parser_options[:on_load] = on_load if on_load
|
|
787
|
+
@parser_config = Ext::Parser::Config.new(parser_options).freeze
|
|
1078
788
|
|
|
1079
|
-
|
|
1080
|
-
@
|
|
789
|
+
generator_options = options.reject { |k, _| EXCLUDED_GENERATOR_OPTIONS.include?(k) }
|
|
790
|
+
@state = State.new(
|
|
791
|
+
**generator_options,
|
|
792
|
+
strict: true,
|
|
793
|
+
as_json: as_json,
|
|
794
|
+
).freeze
|
|
1081
795
|
end
|
|
1082
796
|
|
|
1083
797
|
# call-seq:
|
|
@@ -1136,36 +850,6 @@ end
|
|
|
1136
850
|
module ::Kernel
|
|
1137
851
|
private
|
|
1138
852
|
|
|
1139
|
-
# Outputs _objs_ to STDOUT as JSON strings in the shortest form, that is in
|
|
1140
|
-
# one line.
|
|
1141
|
-
def j(*objs)
|
|
1142
|
-
if RUBY_VERSION >= "3.0"
|
|
1143
|
-
warn "Kernel#j is deprecated and will be removed in json 3.0.0", uplevel: 1, category: :deprecated
|
|
1144
|
-
else
|
|
1145
|
-
warn "Kernel#j is deprecated and will be removed in json 3.0.0", uplevel: 1
|
|
1146
|
-
end
|
|
1147
|
-
|
|
1148
|
-
objs.each do |obj|
|
|
1149
|
-
puts JSON.generate(obj, :allow_nan => true, :max_nesting => false)
|
|
1150
|
-
end
|
|
1151
|
-
nil
|
|
1152
|
-
end
|
|
1153
|
-
|
|
1154
|
-
# Outputs _objs_ to STDOUT as JSON strings in a pretty format, with
|
|
1155
|
-
# indentation and over many lines.
|
|
1156
|
-
def jj(*objs)
|
|
1157
|
-
if RUBY_VERSION >= "3.0"
|
|
1158
|
-
warn "Kernel#jj is deprecated and will be removed in json 3.0.0", uplevel: 1, category: :deprecated
|
|
1159
|
-
else
|
|
1160
|
-
warn "Kernel#jj is deprecated and will be removed in json 3.0.0", uplevel: 1
|
|
1161
|
-
end
|
|
1162
|
-
|
|
1163
|
-
objs.each do |obj|
|
|
1164
|
-
puts JSON.pretty_generate(obj, :allow_nan => true, :max_nesting => false)
|
|
1165
|
-
end
|
|
1166
|
-
nil
|
|
1167
|
-
end
|
|
1168
|
-
|
|
1169
853
|
# If _object_ is string-like, parse the string and return the parsed result as
|
|
1170
854
|
# a Ruby data structure. Otherwise, generate a JSON text from the Ruby data
|
|
1171
855
|
# structure object and return it.
|