json 2.9.0 → 2.10.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 +11 -0
- data/LEGAL +0 -52
- data/README.md +75 -2
- data/ext/json/ext/fbuffer/fbuffer.h +1 -10
- data/ext/json/ext/generator/generator.c +394 -263
- data/ext/json/ext/parser/extconf.rb +1 -0
- data/ext/json/ext/parser/parser.c +769 -2521
- data/json.gemspec +3 -4
- data/lib/json/add/symbol.rb +7 -2
- data/lib/json/common.rb +107 -10
- data/lib/json/ext/generator/state.rb +1 -11
- data/lib/json/ext.rb +26 -4
- data/lib/json/truffle_ruby/generator.rb +111 -50
- data/lib/json/version.rb +1 -1
- metadata +6 -11
- data/ext/json/ext/parser/parser.rl +0 -1457
data/json.gemspec
CHANGED
@@ -11,14 +11,13 @@ spec = Gem::Specification.new do |s|
|
|
11
11
|
s.version = version
|
12
12
|
|
13
13
|
s.summary = "JSON Implementation for Ruby"
|
14
|
-
s.homepage = "https://
|
14
|
+
s.homepage = "https://github.com/ruby/json"
|
15
15
|
s.metadata = {
|
16
16
|
'bug_tracker_uri' => 'https://github.com/ruby/json/issues',
|
17
17
|
'changelog_uri' => 'https://github.com/ruby/json/blob/master/CHANGES.md',
|
18
|
-
'documentation_uri' => 'https://ruby.
|
18
|
+
'documentation_uri' => 'https://docs.ruby-lang.org/en/master/JSON.html',
|
19
19
|
'homepage_uri' => s.homepage,
|
20
20
|
'source_code_uri' => 'https://github.com/ruby/json',
|
21
|
-
'wiki_uri' => 'https://github.com/ruby/json/wiki'
|
22
21
|
}
|
23
22
|
|
24
23
|
s.required_ruby_version = Gem::Requirement.new(">= 2.7")
|
@@ -53,7 +52,7 @@ spec = Gem::Specification.new do |s|
|
|
53
52
|
s.files += Dir["lib/json/ext/**/*.jar"]
|
54
53
|
else
|
55
54
|
s.extensions = Dir["ext/json/**/extconf.rb"]
|
56
|
-
s.files += Dir["ext/json/**/*.{c,h
|
55
|
+
s.files += Dir["ext/json/**/*.{c,h}"]
|
57
56
|
end
|
58
57
|
end
|
59
58
|
|
data/lib/json/add/symbol.rb
CHANGED
@@ -36,8 +36,13 @@ class Symbol
|
|
36
36
|
#
|
37
37
|
# # {"json_class":"Symbol","s":"foo"}
|
38
38
|
#
|
39
|
-
def to_json(*a)
|
40
|
-
|
39
|
+
def to_json(state = nil, *a)
|
40
|
+
state = ::JSON::State.from_state(state)
|
41
|
+
if state.strict?
|
42
|
+
super
|
43
|
+
else
|
44
|
+
as_json.to_json(state, *a)
|
45
|
+
end
|
41
46
|
end
|
42
47
|
|
43
48
|
# See #as_json.
|
data/lib/json/common.rb
CHANGED
@@ -167,6 +167,30 @@ module JSON
|
|
167
167
|
# system. Usually this means that the iconv library is not installed.
|
168
168
|
class MissingUnicodeSupport < JSONError; end
|
169
169
|
|
170
|
+
# Fragment of JSON document that is to be included as is:
|
171
|
+
# fragment = JSON::Fragment.new("[1, 2, 3]")
|
172
|
+
# JSON.generate({ count: 3, items: fragments })
|
173
|
+
#
|
174
|
+
# This allows to easily assemble multiple JSON fragments that have
|
175
|
+
# been persisted somewhere without having to parse them nor resorting
|
176
|
+
# to string interpolation.
|
177
|
+
#
|
178
|
+
# Note: no validation is performed on the provided string. It is the
|
179
|
+
# responsability of the caller to ensure the string contains valid JSON.
|
180
|
+
Fragment = Struct.new(:json) do
|
181
|
+
def initialize(json)
|
182
|
+
unless string = String.try_convert(json)
|
183
|
+
raise TypeError, " no implicit conversion of #{json.class} into String"
|
184
|
+
end
|
185
|
+
|
186
|
+
super(string)
|
187
|
+
end
|
188
|
+
|
189
|
+
def to_json(state = nil, *)
|
190
|
+
json
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
170
194
|
module_function
|
171
195
|
|
172
196
|
# :call-seq:
|
@@ -232,12 +256,13 @@ module JSON
|
|
232
256
|
# - Option +max_nesting+, if not provided, defaults to +false+,
|
233
257
|
# which disables checking for nesting depth.
|
234
258
|
# - Option +allow_nan+, if not provided, defaults to +true+.
|
235
|
-
def parse!(source, opts =
|
236
|
-
|
259
|
+
def parse!(source, opts = nil)
|
260
|
+
options = {
|
237
261
|
:max_nesting => false,
|
238
262
|
:allow_nan => true
|
239
|
-
}
|
240
|
-
|
263
|
+
}
|
264
|
+
options.merge!(opts) if opts
|
265
|
+
Parser.new(source, options).parse
|
241
266
|
end
|
242
267
|
|
243
268
|
# :call-seq:
|
@@ -258,7 +283,7 @@ module JSON
|
|
258
283
|
# JSON.parse!(File.read(path, opts))
|
259
284
|
#
|
260
285
|
# See method #parse!
|
261
|
-
def load_file!(filespec, opts =
|
286
|
+
def load_file!(filespec, opts = nil)
|
262
287
|
parse!(File.read(filespec, encoding: Encoding::UTF_8), opts)
|
263
288
|
end
|
264
289
|
|
@@ -818,11 +843,7 @@ module JSON
|
|
818
843
|
opts = merge_dump_options(opts, **kwargs) if kwargs
|
819
844
|
|
820
845
|
begin
|
821
|
-
|
822
|
-
opts.generate(obj, anIO)
|
823
|
-
else
|
824
|
-
State.generate(obj, opts, anIO)
|
825
|
-
end
|
846
|
+
State.generate(obj, opts, anIO)
|
826
847
|
rescue JSON::NestingError
|
827
848
|
raise ArgumentError, "exceed depth limit"
|
828
849
|
end
|
@@ -841,6 +862,82 @@ module JSON
|
|
841
862
|
class << self
|
842
863
|
private :merge_dump_options
|
843
864
|
end
|
865
|
+
|
866
|
+
# JSON::Coder holds a parser and generator configuration.
|
867
|
+
#
|
868
|
+
# module MyApp
|
869
|
+
# JSONC_CODER = JSON::Coder.new(
|
870
|
+
# allow_trailing_comma: true
|
871
|
+
# )
|
872
|
+
# end
|
873
|
+
#
|
874
|
+
# MyApp::JSONC_CODER.load(document)
|
875
|
+
#
|
876
|
+
class Coder
|
877
|
+
# :call-seq:
|
878
|
+
# JSON.new(options = nil, &block)
|
879
|
+
#
|
880
|
+
# Argument +options+, if given, contains a \Hash of options for both parsing and generating.
|
881
|
+
# See {Parsing Options}[#module-JSON-label-Parsing+Options], and {Generating Options}[#module-JSON-label-Generating+Options].
|
882
|
+
#
|
883
|
+
# For generation, the <tt>strict: true</tt> option is always set. When a Ruby object with no native \JSON counterpart is
|
884
|
+
# encoutered, the block provided to the initialize method is invoked, and must return a Ruby object that has a native
|
885
|
+
# \JSON counterpart:
|
886
|
+
#
|
887
|
+
# module MyApp
|
888
|
+
# API_JSON_CODER = JSON::Coder.new do |object|
|
889
|
+
# case object
|
890
|
+
# when Time
|
891
|
+
# object.iso8601(3)
|
892
|
+
# else
|
893
|
+
# object # Unknown type, will raise
|
894
|
+
# end
|
895
|
+
# end
|
896
|
+
# end
|
897
|
+
#
|
898
|
+
# puts MyApp::API_JSON_CODER.dump(Time.now.utc) # => "2025-01-21T08:41:44.286Z"
|
899
|
+
#
|
900
|
+
def initialize(options = nil, &as_json)
|
901
|
+
if options.nil?
|
902
|
+
options = { strict: true }
|
903
|
+
else
|
904
|
+
options = options.dup
|
905
|
+
options[:strict] = true
|
906
|
+
end
|
907
|
+
options[:as_json] = as_json if as_json
|
908
|
+
options[:create_additions] = false unless options.key?(:create_additions)
|
909
|
+
|
910
|
+
@state = State.new(options).freeze
|
911
|
+
@parser_config = Ext::Parser::Config.new(options)
|
912
|
+
end
|
913
|
+
|
914
|
+
# call-seq:
|
915
|
+
# dump(object) -> String
|
916
|
+
# dump(object, io) -> io
|
917
|
+
#
|
918
|
+
# Serialize the given object into a \JSON document.
|
919
|
+
def dump(object, io = nil)
|
920
|
+
@state.generate_new(object, io)
|
921
|
+
end
|
922
|
+
alias_method :generate, :dump
|
923
|
+
|
924
|
+
# call-seq:
|
925
|
+
# load(string) -> Object
|
926
|
+
#
|
927
|
+
# Parse the given \JSON document and return an equivalent Ruby object.
|
928
|
+
def load(source)
|
929
|
+
@parser_config.parse(source)
|
930
|
+
end
|
931
|
+
alias_method :parse, :load
|
932
|
+
|
933
|
+
# call-seq:
|
934
|
+
# load(path) -> Object
|
935
|
+
#
|
936
|
+
# Parse the given \JSON document and return an equivalent Ruby object.
|
937
|
+
def load_file(path)
|
938
|
+
load(File.read(path, encoding: Encoding::UTF_8))
|
939
|
+
end
|
940
|
+
end
|
844
941
|
end
|
845
942
|
|
846
943
|
module ::Kernel
|
@@ -47,17 +47,6 @@ module JSON
|
|
47
47
|
|
48
48
|
alias_method :merge, :configure
|
49
49
|
|
50
|
-
# call-seq:
|
51
|
-
# generate(obj) -> String
|
52
|
-
# generate(obj, anIO) -> anIO
|
53
|
-
#
|
54
|
-
# Generates a valid JSON document from object +obj+ and returns the
|
55
|
-
# result. If no valid JSON document can be created this method raises a
|
56
|
-
# GeneratorError exception.
|
57
|
-
def generate(obj, io = nil)
|
58
|
-
_generate(obj, io)
|
59
|
-
end
|
60
|
-
|
61
50
|
# call-seq: to_h
|
62
51
|
#
|
63
52
|
# Returns the configuration instance variables as a hash, that can be
|
@@ -69,6 +58,7 @@ module JSON
|
|
69
58
|
space_before: space_before,
|
70
59
|
object_nl: object_nl,
|
71
60
|
array_nl: array_nl,
|
61
|
+
as_json: as_json,
|
72
62
|
allow_nan: allow_nan?,
|
73
63
|
ascii_only: ascii_only?,
|
74
64
|
max_nesting: max_nesting,
|
data/lib/json/ext.rb
CHANGED
@@ -6,15 +6,37 @@ module JSON
|
|
6
6
|
# This module holds all the modules/classes that implement JSON's
|
7
7
|
# functionality as C extensions.
|
8
8
|
module Ext
|
9
|
+
class Parser
|
10
|
+
class << self
|
11
|
+
def parse(...)
|
12
|
+
new(...).parse
|
13
|
+
end
|
14
|
+
alias_method :parse, :parse # Allow redefinition by extensions
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(source, opts = nil)
|
18
|
+
@source = source
|
19
|
+
@config = Config.new(opts)
|
20
|
+
end
|
21
|
+
|
22
|
+
def source
|
23
|
+
@source.dup
|
24
|
+
end
|
25
|
+
|
26
|
+
def parse
|
27
|
+
@config.parse(@source)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
require 'json/ext/parser'
|
32
|
+
Ext::Parser::Config = Ext::ParserConfig
|
33
|
+
JSON.parser = Ext::Parser
|
34
|
+
|
9
35
|
if RUBY_ENGINE == 'truffleruby'
|
10
|
-
require 'json/ext/parser'
|
11
36
|
require 'json/truffle_ruby/generator'
|
12
|
-
JSON.parser = Parser
|
13
37
|
JSON.generator = ::JSON::TruffleRuby::Generator
|
14
38
|
else
|
15
|
-
require 'json/ext/parser'
|
16
39
|
require 'json/ext/generator'
|
17
|
-
JSON.parser = Parser
|
18
40
|
JSON.generator = Generator
|
19
41
|
end
|
20
42
|
end
|
@@ -39,30 +39,33 @@ module JSON
|
|
39
39
|
'\\' => '\\\\',
|
40
40
|
}.freeze # :nodoc:
|
41
41
|
|
42
|
-
ESCAPE_PATTERN = /[\/"\\\x0-\x1f]/n # :nodoc:
|
43
|
-
|
44
42
|
SCRIPT_SAFE_MAP = MAP.merge(
|
45
43
|
'/' => '\\/',
|
46
|
-
"\u2028"
|
47
|
-
"\u2029"
|
44
|
+
"\u2028" => '\u2028',
|
45
|
+
"\u2029" => '\u2029',
|
48
46
|
).freeze
|
49
47
|
|
50
|
-
SCRIPT_SAFE_ESCAPE_PATTERN =
|
48
|
+
SCRIPT_SAFE_ESCAPE_PATTERN = /[\/"\\\x0-\x1f\u2028-\u2029]/
|
51
49
|
|
52
50
|
# Convert a UTF8 encoded Ruby string _string_ to a JSON string, encoded with
|
53
51
|
# UTF16 big endian characters as \u????, and return it.
|
54
|
-
def utf8_to_json(string, script_safe = false) # :nodoc:
|
55
|
-
string = string.b
|
52
|
+
def self.utf8_to_json(string, script_safe = false) # :nodoc:
|
56
53
|
if script_safe
|
57
|
-
|
54
|
+
if SCRIPT_SAFE_ESCAPE_PATTERN.match?(string)
|
55
|
+
string.gsub(SCRIPT_SAFE_ESCAPE_PATTERN, SCRIPT_SAFE_MAP)
|
56
|
+
else
|
57
|
+
string
|
58
|
+
end
|
58
59
|
else
|
59
|
-
|
60
|
+
if /["\\\x0-\x1f]/.match?(string)
|
61
|
+
string.gsub(/["\\\x0-\x1f]/, MAP)
|
62
|
+
else
|
63
|
+
string
|
64
|
+
end
|
60
65
|
end
|
61
|
-
string.force_encoding(::Encoding::UTF_8)
|
62
|
-
string
|
63
66
|
end
|
64
67
|
|
65
|
-
def utf8_to_json_ascii(original_string, script_safe = false) # :nodoc:
|
68
|
+
def self.utf8_to_json_ascii(original_string, script_safe = false) # :nodoc:
|
66
69
|
string = original_string.b
|
67
70
|
map = script_safe ? SCRIPT_SAFE_MAP : MAP
|
68
71
|
string.gsub!(/[\/"\\\x0-\x1f]/n) { map[$&] || $& }
|
@@ -86,24 +89,17 @@ module JSON
|
|
86
89
|
raise GeneratorError.new(e.message, original_string)
|
87
90
|
end
|
88
91
|
|
89
|
-
def valid_utf8?(string)
|
92
|
+
def self.valid_utf8?(string)
|
90
93
|
encoding = string.encoding
|
91
94
|
(encoding == Encoding::UTF_8 || encoding == Encoding::ASCII) &&
|
92
95
|
string.valid_encoding?
|
93
96
|
end
|
94
|
-
module_function :utf8_to_json, :utf8_to_json_ascii, :valid_utf8?
|
95
97
|
|
96
98
|
# This class is used to create State instances, that are use to hold data
|
97
99
|
# while generating a JSON text from a Ruby data structure.
|
98
100
|
class State
|
99
101
|
def self.generate(obj, opts = nil, io = nil)
|
100
|
-
|
101
|
-
if io
|
102
|
-
io.write(string)
|
103
|
-
io
|
104
|
-
else
|
105
|
-
string
|
106
|
-
end
|
102
|
+
new(opts).generate(obj, io)
|
107
103
|
end
|
108
104
|
|
109
105
|
# Creates a State object from _opts_, which ought to be Hash to create
|
@@ -111,16 +107,17 @@ module JSON
|
|
111
107
|
# an unconfigured instance. If _opts_ is a State object, it is just
|
112
108
|
# returned.
|
113
109
|
def self.from_state(opts)
|
114
|
-
|
115
|
-
|
116
|
-
opts
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
110
|
+
if opts
|
111
|
+
case
|
112
|
+
when self === opts
|
113
|
+
return opts
|
114
|
+
when opts.respond_to?(:to_hash)
|
115
|
+
return new(opts.to_hash)
|
116
|
+
when opts.respond_to?(:to_h)
|
117
|
+
return new(opts.to_h)
|
118
|
+
end
|
123
119
|
end
|
120
|
+
SAFE_STATE_PROTOTYPE.dup
|
124
121
|
end
|
125
122
|
|
126
123
|
# Instantiates a new State object, configured by _opts_.
|
@@ -148,6 +145,7 @@ module JSON
|
|
148
145
|
@array_nl = ''
|
149
146
|
@allow_nan = false
|
150
147
|
@ascii_only = false
|
148
|
+
@as_json = false
|
151
149
|
@depth = 0
|
152
150
|
@buffer_initial_length = 1024
|
153
151
|
@script_safe = false
|
@@ -173,6 +171,9 @@ module JSON
|
|
173
171
|
# This string is put at the end of a line that holds a JSON array.
|
174
172
|
attr_accessor :array_nl
|
175
173
|
|
174
|
+
# This proc converts unsupported types into native JSON types.
|
175
|
+
attr_accessor :as_json
|
176
|
+
|
176
177
|
# This integer returns the maximum level of data structure nesting in
|
177
178
|
# the generated JSON, max_nesting = 0 if no maximum is checked.
|
178
179
|
attr_accessor :max_nesting
|
@@ -257,6 +258,7 @@ module JSON
|
|
257
258
|
@object_nl = opts[:object_nl] || '' if opts.key?(:object_nl)
|
258
259
|
@array_nl = opts[:array_nl] || '' if opts.key?(:array_nl)
|
259
260
|
@allow_nan = !!opts[:allow_nan] if opts.key?(:allow_nan)
|
261
|
+
@as_json = opts[:as_json].to_proc if opts.key?(:as_json)
|
260
262
|
@ascii_only = opts[:ascii_only] if opts.key?(:ascii_only)
|
261
263
|
@depth = opts[:depth] || 0
|
262
264
|
@buffer_initial_length ||= opts[:buffer_initial_length]
|
@@ -299,9 +301,9 @@ module JSON
|
|
299
301
|
# returns the result. If no valid JSON document can be
|
300
302
|
# created this method raises a
|
301
303
|
# GeneratorError exception.
|
302
|
-
def generate(obj)
|
304
|
+
def generate(obj, anIO = nil)
|
303
305
|
if @indent.empty? and @space.empty? and @space_before.empty? and @object_nl.empty? and @array_nl.empty? and
|
304
|
-
!@ascii_only and !@script_safe and @max_nesting == 0 and !@strict
|
306
|
+
!@ascii_only and !@script_safe and @max_nesting == 0 and (!@strict || Symbol === obj)
|
305
307
|
result = generate_json(obj, ''.dup)
|
306
308
|
else
|
307
309
|
result = obj.to_json(self)
|
@@ -310,7 +312,16 @@ module JSON
|
|
310
312
|
"source sequence #{result.inspect} is illegal/malformed utf-8",
|
311
313
|
obj
|
312
314
|
)
|
313
|
-
|
315
|
+
if anIO
|
316
|
+
anIO.write(result)
|
317
|
+
anIO
|
318
|
+
else
|
319
|
+
result
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
def generate_new(obj, anIO = nil) # :nodoc:
|
324
|
+
dup.generate(obj, anIO)
|
314
325
|
end
|
315
326
|
|
316
327
|
# Handles @allow_nan, @buffer_initial_length, other ivars must be the default value (see above)
|
@@ -353,6 +364,12 @@ module JSON
|
|
353
364
|
end
|
354
365
|
when Integer
|
355
366
|
buf << obj.to_s
|
367
|
+
when Symbol
|
368
|
+
if @strict
|
369
|
+
fast_serialize_string(obj.name, buf)
|
370
|
+
else
|
371
|
+
buf << obj.to_json(self)
|
372
|
+
end
|
356
373
|
else
|
357
374
|
# Note: Float is handled this way since Float#to_s is slow anyway
|
358
375
|
buf << obj.to_json(self)
|
@@ -371,8 +388,8 @@ module JSON
|
|
371
388
|
end
|
372
389
|
raise GeneratorError.new("source sequence is illegal/malformed utf-8", string) unless string.valid_encoding?
|
373
390
|
|
374
|
-
if /["\\\x0-\x1f]
|
375
|
-
buf << string.gsub(/["\\\x0-\x1f]
|
391
|
+
if /["\\\x0-\x1f]/.match?(string)
|
392
|
+
buf << string.gsub(/["\\\x0-\x1f]/, MAP)
|
376
393
|
else
|
377
394
|
buf << string
|
378
395
|
end
|
@@ -404,8 +421,20 @@ module JSON
|
|
404
421
|
# it to a JSON string, and returns the result. This is a fallback, if no
|
405
422
|
# special method #to_json was defined for some object.
|
406
423
|
def to_json(state = nil, *)
|
407
|
-
|
408
|
-
|
424
|
+
state = State.from_state(state) if state
|
425
|
+
if state&.strict?
|
426
|
+
value = self
|
427
|
+
if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value)
|
428
|
+
if state.as_json
|
429
|
+
value = state.as_json.call(value)
|
430
|
+
unless false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value
|
431
|
+
raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
|
432
|
+
end
|
433
|
+
value.to_json(state)
|
434
|
+
else
|
435
|
+
raise GeneratorError.new("#{value.class} not allowed in JSON", value)
|
436
|
+
end
|
437
|
+
end
|
409
438
|
else
|
410
439
|
to_s.to_json
|
411
440
|
end
|
@@ -455,8 +484,16 @@ module JSON
|
|
455
484
|
end
|
456
485
|
|
457
486
|
result = +"#{result}#{key_json}#{state.space_before}:#{state.space}"
|
458
|
-
if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value)
|
459
|
-
|
487
|
+
if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value)
|
488
|
+
if state.as_json
|
489
|
+
value = state.as_json.call(value)
|
490
|
+
unless false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value
|
491
|
+
raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
|
492
|
+
end
|
493
|
+
result << value.to_json(state)
|
494
|
+
else
|
495
|
+
raise GeneratorError.new("#{value.class} not allowed in JSON", value)
|
496
|
+
end
|
460
497
|
elsif value.respond_to?(:to_json)
|
461
498
|
result << value.to_json(state)
|
462
499
|
else
|
@@ -508,8 +545,16 @@ module JSON
|
|
508
545
|
each { |value|
|
509
546
|
result << delim unless first
|
510
547
|
result << state.indent * depth if indent
|
511
|
-
if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value)
|
512
|
-
|
548
|
+
if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value || Symbol == value)
|
549
|
+
if state.as_json
|
550
|
+
value = state.as_json.call(value)
|
551
|
+
unless false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value || Symbol === value
|
552
|
+
raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
|
553
|
+
end
|
554
|
+
result << value.to_json(state)
|
555
|
+
else
|
556
|
+
raise GeneratorError.new("#{value.class} not allowed in JSON", value)
|
557
|
+
end
|
513
558
|
elsif value.respond_to?(:to_json)
|
514
559
|
result << value.to_json(state)
|
515
560
|
else
|
@@ -531,18 +576,23 @@ module JSON
|
|
531
576
|
|
532
577
|
module Float
|
533
578
|
# Returns a JSON string representation for this Float number.
|
534
|
-
def to_json(state = nil, *)
|
579
|
+
def to_json(state = nil, *args)
|
535
580
|
state = State.from_state(state)
|
536
|
-
|
537
|
-
when infinite?
|
538
|
-
if state.allow_nan?
|
539
|
-
to_s
|
540
|
-
else
|
541
|
-
raise GeneratorError.new("#{self} not allowed in JSON", self)
|
542
|
-
end
|
543
|
-
when nan?
|
581
|
+
if infinite? || nan?
|
544
582
|
if state.allow_nan?
|
545
583
|
to_s
|
584
|
+
elsif state.strict? && state.as_json
|
585
|
+
casted_value = state.as_json.call(self)
|
586
|
+
|
587
|
+
if casted_value.equal?(self)
|
588
|
+
raise GeneratorError.new("#{self} not allowed in JSON", self)
|
589
|
+
end
|
590
|
+
|
591
|
+
state.check_max_nesting
|
592
|
+
state.depth += 1
|
593
|
+
result = casted_value.to_json(state, *args)
|
594
|
+
state.depth -= 1
|
595
|
+
result
|
546
596
|
else
|
547
597
|
raise GeneratorError.new("#{self} not allowed in JSON", self)
|
548
598
|
end
|
@@ -552,6 +602,17 @@ module JSON
|
|
552
602
|
end
|
553
603
|
end
|
554
604
|
|
605
|
+
module Symbol
|
606
|
+
def to_json(state = nil, *args)
|
607
|
+
state = State.from_state(state)
|
608
|
+
if state.strict?
|
609
|
+
name.to_json(state, *args)
|
610
|
+
else
|
611
|
+
super
|
612
|
+
end
|
613
|
+
end
|
614
|
+
end
|
615
|
+
|
555
616
|
module String
|
556
617
|
# This string should be encoded with UTF-8 A call to this method
|
557
618
|
# returns a JSON string encoded with UTF16 big endian characters as
|
data/lib/json/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: json
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Florian Frank
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 2025-02-10 00:00:00.000000000 Z
|
12
11
|
dependencies: []
|
13
12
|
description: This is a JSON implementation as a Ruby extension in C.
|
14
13
|
email: flori@ping.de
|
@@ -29,7 +28,6 @@ files:
|
|
29
28
|
- ext/json/ext/generator/generator.c
|
30
29
|
- ext/json/ext/parser/extconf.rb
|
31
30
|
- ext/json/ext/parser/parser.c
|
32
|
-
- ext/json/ext/parser/parser.rl
|
33
31
|
- json.gemspec
|
34
32
|
- lib/json.rb
|
35
33
|
- lib/json/add/bigdecimal.rb
|
@@ -52,17 +50,15 @@ files:
|
|
52
50
|
- lib/json/generic_object.rb
|
53
51
|
- lib/json/truffle_ruby/generator.rb
|
54
52
|
- lib/json/version.rb
|
55
|
-
homepage: https://
|
53
|
+
homepage: https://github.com/ruby/json
|
56
54
|
licenses:
|
57
55
|
- Ruby
|
58
56
|
metadata:
|
59
57
|
bug_tracker_uri: https://github.com/ruby/json/issues
|
60
58
|
changelog_uri: https://github.com/ruby/json/blob/master/CHANGES.md
|
61
|
-
documentation_uri: https://ruby.
|
62
|
-
homepage_uri: https://
|
59
|
+
documentation_uri: https://docs.ruby-lang.org/en/master/JSON.html
|
60
|
+
homepage_uri: https://github.com/ruby/json
|
63
61
|
source_code_uri: https://github.com/ruby/json
|
64
|
-
wiki_uri: https://github.com/ruby/json/wiki
|
65
|
-
post_install_message:
|
66
62
|
rdoc_options:
|
67
63
|
- "--title"
|
68
64
|
- JSON implementation for Ruby
|
@@ -81,8 +77,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
81
77
|
- !ruby/object:Gem::Version
|
82
78
|
version: '0'
|
83
79
|
requirements: []
|
84
|
-
rubygems_version: 3.
|
85
|
-
signing_key:
|
80
|
+
rubygems_version: 3.6.2
|
86
81
|
specification_version: 4
|
87
82
|
summary: JSON Implementation for Ruby
|
88
83
|
test_files: []
|