json 2.21.2-java → 3.0.0-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.
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 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
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
- class << self
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, do_raise)
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
- message = "detected duplicate key #{key_str.inspect} in #{hash.inspect}"
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
@@ -257,7 +142,56 @@ module JSON
257
142
 
258
143
  # This exception is raised if a parser error occurs.
259
144
  class ParserError < JSONError
260
- attr_reader :line, :column
145
+ # Line number where the parser encountered an error.
146
+ # Is <tt>nil</tt> when raised by JSON::ResumableParser.
147
+ attr_reader :line
148
+
149
+ # Column number where the parser encountered an error.
150
+ # Is <tt>nil</tt> when raised by JSON::ResumableParser.
151
+ attr_reader :column
152
+
153
+ # Returns a best effort JSONPath string representing where in the document
154
+ # the parser encountered an error:
155
+ #
156
+ # begin
157
+ # JSON.parse('{"articles": [ { "title": invalid } ]}')
158
+ # rescue JSON::ParserError => error
159
+ # error.json_path # => "$.articles[0].title"
160
+ # end
161
+ def json_path
162
+ return @json_path if String === @json_path
163
+
164
+ if Array === @json_path
165
+ path = build_json_path(@json_path)
166
+ @json_path = path unless frozen?
167
+ return path
168
+ end
169
+ end
170
+
171
+ private
172
+
173
+ def build_json_path(segments)
174
+ error = false
175
+ path = segments.filter_map do |segment|
176
+ next if error
177
+
178
+ case segment
179
+ when Integer
180
+ "[#{segment}]"
181
+ when String, Symbol
182
+ if segment.match?(/\A[a-zA-Z\$\_][a-zA-Z\$\_0-9]*\z/)
183
+ ".#{segment}"
184
+ else
185
+ segment = segment.to_s.gsub(/["\\]/, { '"' => '\\"', '\\' => '\\\\' })
186
+ %{["#{segment}"]}
187
+ end
188
+ else
189
+ error = true
190
+ nil
191
+ end
192
+ end.join
193
+ "$#{path}".freeze
194
+ end
261
195
  end
262
196
 
263
197
  # This exception is raised if the nesting of parsed data structures is too
@@ -356,19 +290,17 @@ module JSON
356
290
  # ---
357
291
  #
358
292
  # Raises an exception if +source+ is not valid JSON:
359
- # # Raises JSON::ParserError (783: unexpected token at ''):
360
- # JSON.parse('')
293
+ # # Raises JSON::ParserError unexpected character: 'invalid' at line 1 column 1 :
294
+ # JSON.parse('invalid')
361
295
  #
362
- def parse(source, opts = nil)
363
- opts = ParserOptions.prepare(opts) unless opts.nil?
364
- Parser.parse(source, opts)
365
- end
296
+ def parse(source, on_load: nil, object_class: nil, array_class: nil, **options)
297
+ if object_class || array_class
298
+ on_load = ParserOptions.on_load(on_load, object_class, array_class)
299
+ end
366
300
 
367
- PARSE_L_OPTIONS = {
368
- max_nesting: false,
369
- allow_nan: true,
370
- }.freeze
371
- private_constant :PARSE_L_OPTIONS
301
+ options[:on_load] = on_load if on_load
302
+ Parser.parse(source, options)
303
+ end
372
304
 
373
305
  # :call-seq:
374
306
  # JSON.parse!(source, opts) -> object
@@ -381,34 +313,30 @@ module JSON
381
313
  # - Option +max_nesting+, if not provided, defaults to +false+,
382
314
  # which disables checking for nesting depth.
383
315
  # - Option +allow_nan+, if not provided, defaults to +true+.
384
- def parse!(source, opts = nil)
385
- if opts.nil?
386
- parse(source, PARSE_L_OPTIONS)
387
- else
388
- parse(source, PARSE_L_OPTIONS.merge(opts))
389
- end
316
+ def parse!(source, **options)
317
+ parse(source, max_nesting: false, allow_nan: true, **options)
390
318
  end
391
319
 
392
320
  # :call-seq:
393
- # JSON.load_file(path, opts={}) -> object
321
+ # JSON.load_file(path, **) -> object
394
322
  #
395
323
  # Calls:
396
- # parse(File.read(path), opts)
324
+ # parse(File.read(path), **)
397
325
  #
398
326
  # See method #parse.
399
- def load_file(filespec, opts = nil)
400
- parse(File.read(filespec, encoding: Encoding::UTF_8), opts)
327
+ def load_file(filespec, ...)
328
+ parse(File.read(filespec, encoding: Encoding::UTF_8), ...)
401
329
  end
402
330
 
403
331
  # :call-seq:
404
- # JSON.load_file!(path, opts = {})
332
+ # JSON.load_file!(path, **)
405
333
  #
406
334
  # Calls:
407
- # JSON.parse!(File.read(path, opts))
335
+ # JSON.parse!(File.read(path), **)
408
336
  #
409
337
  # See method #parse!
410
- def load_file!(filespec, opts = nil)
411
- parse!(File.read(filespec, encoding: Encoding::UTF_8), opts)
338
+ def load_file!(filespec, ...)
339
+ parse!(File.read(filespec, encoding: Encoding::UTF_8), ...)
412
340
  end
413
341
 
414
342
  # :call-seq:
@@ -451,32 +379,10 @@ module JSON
451
379
  if State === opts
452
380
  opts.generate(obj)
453
381
  else
454
- State.generate(obj, opts, nil)
382
+ State.generate(obj, opts.frozen? ? opts : opts.dup, nil)
455
383
  end
456
384
  end
457
385
 
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
476
- end
477
- generate(obj, opts)
478
- end
479
-
480
386
  PRETTY_GENERATE_OPTIONS = {
481
387
  indent: ' ',
482
388
  space: ' ',
@@ -530,43 +436,20 @@ module JSON
530
436
  raise TypeError, "can't convert #{opts.class} into Hash"
531
437
  end
532
438
  end
439
+
533
440
  options = options.merge(opts)
534
441
  end
535
442
 
536
443
  State.generate(obj, options, nil)
537
444
  end
538
445
 
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
446
  # :call-seq:
564
447
  # JSON.unsafe_load(source, options = {}) -> object
565
448
  # JSON.unsafe_load(source, proc = nil, options = {}) -> object
566
449
  #
567
450
  # Returns the Ruby objects created by parsing the given +source+.
568
451
  #
569
- # BEWARE: This method is meant to serialise data from trusted user input,
452
+ # BEWARE: This method is meant to deserialise data from trusted user input,
570
453
  # like from your own database server or clients under your control, it could
571
454
  # be dangerous to allow untrusted users to pass JSON sources into it.
572
455
  #
@@ -586,7 +469,6 @@ module JSON
586
469
  # See details below.
587
470
  # - Argument +opts+, if given, contains a \Hash of options for the parsing.
588
471
  # See {Parsing Options}[#module-JSON-label-Parsing+Options].
589
- # The default options can be changed via method JSON.unsafe_load_default_options=.
590
472
  #
591
473
  # ---
592
474
  #
@@ -691,38 +573,8 @@ module JSON
691
573
  # #<Admin:0x00000000064c41f8
692
574
  # @attributes={"type"=>"Admin", "password"=>"0wn3d"}>}
693
575
  #
694
- def unsafe_load(source, proc = nil, options = nil)
695
- opts = if options.nil?
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)
576
+ def unsafe_load(source, proc = nil, **options)
577
+ load(source, proc, max_nesting: false, **options)
726
578
  end
727
579
 
728
580
  # :call-seq:
@@ -731,16 +583,6 @@ module JSON
731
583
  #
732
584
  # Returns the Ruby objects created by parsing the given +source+.
733
585
  #
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
586
  # - Argument +source+ must be, or be convertible to, a \String:
745
587
  # - If +source+ responds to instance method +to_str+,
746
588
  # <tt>source.to_str</tt> becomes the source.
@@ -757,7 +599,6 @@ module JSON
757
599
  # See details below.
758
600
  # - Argument +opts+, if given, contains a \Hash of options for the parsing.
759
601
  # See {Parsing Options}[#module-JSON-label-Parsing+Options].
760
- # The default options can be changed via method JSON.load_default_options=.
761
602
  #
762
603
  # ---
763
604
  #
@@ -862,23 +703,7 @@ module JSON
862
703
  # #<Admin:0x00000000064c41f8
863
704
  # @attributes={"type"=>"Admin", "password"=>"0wn3d"}>}
864
705
  #
865
- def load(source, proc = nil, options = 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
-
706
+ def load(source, proc = nil, allow_blank: true, **options)
882
707
  unless source.is_a?(String)
883
708
  if source.respond_to? :to_str
884
709
  source = source.to_str
@@ -889,30 +714,19 @@ module JSON
889
714
  end
890
715
  end
891
716
 
892
- if opts[:allow_blank] && (source.nil? || (String === source && source.empty?))
717
+ if allow_blank && (source.nil? || (String === source && source.empty?))
893
718
  source = 'null'
894
719
  end
895
720
 
896
721
  if proc
897
- opts = opts.dup
898
- opts[:on_load] = proc.to_proc
722
+ parse(source, allow_nan: true, on_load: proc.to_proc, **options)
723
+ else
724
+ parse(source, allow_nan: true, **options)
899
725
  end
900
-
901
- parse(source, opts)
902
726
  end
903
727
 
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
728
  # :call-seq:
915
- # JSON.dump(obj, io = nil, limit = nil)
729
+ # JSON.dump(obj, io = nil, options = nil)
916
730
  #
917
731
  # Dumps +obj+ as a \JSON string, i.e. calls generate on the object and returns the result.
918
732
  #
@@ -921,7 +735,6 @@ module JSON
921
735
  # - Argument +io+, if given, should respond to method +write+;
922
736
  # the \JSON \String is written to +io+, and +io+ is returned.
923
737
  # 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
738
  #
926
739
  # ---
927
740
  #
@@ -938,100 +751,26 @@ module JSON
938
751
  # puts File.read(path)
939
752
  # Output:
940
753
  # {"foo":[0,1],"bar":{"baz":2,"bat":3},"bam":"bad"}
941
- def dump(obj, anIO = nil, limit = nil, kwargs = nil)
754
+ def dump(obj, anIO = nil, kwargs = nil)
942
755
  if kwargs.nil?
943
- if limit.nil?
944
- if anIO.is_a?(Hash)
945
- kwargs = anIO
946
- anIO = nil
947
- end
948
- elsif limit.is_a?(Hash)
949
- kwargs = limit
950
- limit = nil
756
+ if anIO.is_a?(Hash)
757
+ kwargs = anIO
758
+ anIO = nil
951
759
  end
952
760
  end
953
761
 
954
- unless anIO.nil?
955
- if anIO.respond_to?(:to_io)
956
- anIO = anIO.to_io
957
- elsif limit.nil? && !anIO.respond_to?(:write)
958
- anIO, limit = nil, anIO
959
- end
762
+ if anIO&.respond_to?(:to_io)
763
+ anIO = anIO.to_io
960
764
  end
961
765
 
962
- opts = JSON._dump_default_options
963
- opts = opts.merge(:max_nesting => limit) if limit
964
- opts = opts.merge(kwargs) if kwargs
766
+ opts = {
767
+ allow_nan: true,
768
+ }
769
+ opts.merge!(kwargs) if kwargs
965
770
 
966
- begin
967
- State.generate(obj, opts, anIO)
968
- rescue JSON::NestingError
969
- raise ArgumentError, "exceed depth limit"
970
- end
771
+ State.generate(obj, opts, anIO)
971
772
  end
972
773
 
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
991
- end
992
- generate(...)
993
- end
994
- module_function :fast_unparse
995
-
996
- def pretty_unparse(...)
997
- if RUBY_VERSION >= "3.0"
998
- warn "JSON.pretty_unparse is deprecated and will be removed in json 3.0.0, just use JSON.pretty_generate", uplevel: 1, category: :deprecated
999
- else
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
1005
-
1006
- def restore(...)
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
1032
- end
1033
- # :startdoc:
1034
-
1035
774
  # JSON::Coder holds a parser and generator configuration.
1036
775
  #
1037
776
  # module MyApp
@@ -1043,6 +782,27 @@ module JSON
1043
782
  # MyApp::JSONC_CODER.load(document)
1044
783
  #
1045
784
  class Coder
785
+ PARSER_OPTIONS = %i(
786
+ max_nesting
787
+ allow_nan
788
+ allow_trailing_comma
789
+ allow_comments
790
+ allow_control_characters
791
+ allow_invalid_escape
792
+ symbolize_names
793
+ freeze
794
+ allow_duplicate_key
795
+ decimal_class
796
+ ).freeze
797
+ private_constant :PARSER_OPTIONS
798
+
799
+ EXCLUDED_GENERATOR_OPTIONS = (PARSER_OPTIONS - %i(
800
+ max_nesting
801
+ allow_nan
802
+ allow_duplicate_key
803
+ )).freeze
804
+ private_constant :EXCLUDED_GENERATOR_OPTIONS
805
+
1046
806
  # :call-seq:
1047
807
  # JSON.new(options = nil, &block)
1048
808
  #
@@ -1067,17 +827,20 @@ module JSON
1067
827
  #
1068
828
  # puts MyApp::API_JSON_CODER.dump(Time.now.utc) # => "2025-01-21T08:41:44.286Z"
1069
829
  #
1070
- def initialize(options = nil, &as_json)
1071
- if options.nil?
1072
- options = { strict: true }
1073
- else
1074
- options = options.dup
1075
- options[:strict] = true
830
+ def initialize(object_class: nil, array_class: nil, on_load: nil, **options, &as_json)
831
+ if object_class || array_class
832
+ on_load = ParserOptions.on_load(on_load, object_class, array_class)
1076
833
  end
1077
- options[:as_json] = as_json if as_json
834
+ parser_options = options.slice(*PARSER_OPTIONS)
835
+ parser_options[:on_load] = on_load if on_load
836
+ @parser_config = Ext::Parser::Config.new(parser_options).freeze
1078
837
 
1079
- @state = State.new(options).freeze
1080
- @parser_config = Ext::Parser::Config.new(ParserOptions.prepare(options)).freeze
838
+ generator_options = options.reject { |k, _| EXCLUDED_GENERATOR_OPTIONS.include?(k) }
839
+ @state = State.new(
840
+ **generator_options,
841
+ strict: true,
842
+ as_json: as_json,
843
+ ).freeze
1081
844
  end
1082
845
 
1083
846
  # call-seq:
@@ -1136,36 +899,6 @@ end
1136
899
  module ::Kernel
1137
900
  private
1138
901
 
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
902
  # If _object_ is string-like, parse the string and return the parsed result as
1170
903
  # a Ruby data structure. Otherwise, generate a JSON text from the Ruby data
1171
904
  # structure object and return it.