json 2.13.2 → 3.0.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 +208 -8
- data/LEGAL +12 -0
- data/README.md +34 -87
- data/ext/json/ext/fbuffer/fbuffer.h +75 -86
- data/ext/json/ext/generator/extconf.rb +4 -1
- data/ext/json/ext/generator/generator.c +494 -596
- data/ext/json/ext/json.h +196 -0
- data/ext/json/ext/parser/extconf.rb +29 -1
- data/ext/json/ext/parser/parser.c +2091 -723
- data/ext/json/ext/simd/simd.h +42 -22
- data/ext/json/ext/vendor/fast_float_parser.h +814 -0
- data/ext/json/ext/vendor/fpconv.c +13 -12
- data/lib/json/common.rb +199 -389
- data/lib/json/ext/generator/state.rb +8 -37
- data/lib/json/ext.rb +25 -1
- data/lib/json/truffle_ruby/generator.rb +186 -128
- data/lib/json/version.rb +1 -1
- data/lib/json.rb +84 -252
- metadata +5 -18
- data/lib/json/add/bigdecimal.rb +0 -58
- data/lib/json/add/complex.rb +0 -51
- data/lib/json/add/core.rb +0 -12
- 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/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 -75
data/lib/json.rb
CHANGED
|
@@ -6,6 +6,15 @@ require 'json/common'
|
|
|
6
6
|
#
|
|
7
7
|
# \JSON is a lightweight data-interchange format.
|
|
8
8
|
#
|
|
9
|
+
# \JSON is easy for us humans to read and write,
|
|
10
|
+
# and equally simple for machines to read (parse) and write (generate).
|
|
11
|
+
#
|
|
12
|
+
# \JSON is language-independent, making it an ideal interchange format
|
|
13
|
+
# for applications in differing programming languages
|
|
14
|
+
# and on differing operating systems.
|
|
15
|
+
#
|
|
16
|
+
# == \JSON Values
|
|
17
|
+
#
|
|
9
18
|
# A \JSON value is one of the following:
|
|
10
19
|
# - Double-quoted text: <tt>"foo"</tt>.
|
|
11
20
|
# - Number: +1+, +1.0+, +2.0e2+.
|
|
@@ -112,9 +121,11 @@ require 'json/common'
|
|
|
112
121
|
# ====== Input Options
|
|
113
122
|
#
|
|
114
123
|
# Option +max_nesting+ (\Integer) specifies the maximum nesting depth allowed;
|
|
115
|
-
# defaults to +100+;
|
|
124
|
+
# defaults to +100+;
|
|
125
|
+
# You can set it to +false+ to disable depth checking entirely, but that is dangerous
|
|
126
|
+
# when parsing untrusted input.
|
|
116
127
|
#
|
|
117
|
-
# With the default, +
|
|
128
|
+
# With the default, +100+:
|
|
118
129
|
# source = '[0, [1, [2, [3]]]]'
|
|
119
130
|
# ruby = JSON.parse(source)
|
|
120
131
|
# ruby # => [0, [1, [2, [3]]]]
|
|
@@ -130,18 +141,12 @@ require 'json/common'
|
|
|
130
141
|
# Option +allow_duplicate_key+ specifies whether duplicate keys in objects
|
|
131
142
|
# should be ignored or cause an error to be raised:
|
|
132
143
|
#
|
|
133
|
-
# When
|
|
134
|
-
#
|
|
135
|
-
# JSON.parse('{"a": 1, "a":2}') => {"a" => 2}
|
|
136
|
-
# # waring: detected duplicate keys in JSON object.
|
|
137
|
-
# # This will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`
|
|
144
|
+
# When set to +false+, the default:
|
|
145
|
+
# JSON.parse('{"a": 1, "a":2}') => duplicate key at line 1 column 1 (JSON::ParserError)
|
|
138
146
|
#
|
|
139
|
-
# When set to
|
|
147
|
+
# When set to +true+:
|
|
140
148
|
# # The last value is used.
|
|
141
|
-
# JSON.parse('{"a": 1, "a":2}') => {"a" => 2}
|
|
142
|
-
#
|
|
143
|
-
# When set to `+false+`, the future default:
|
|
144
|
-
# JSON.parse('{"a": 1, "a":2}') => duplicate key at line 1 column 1 (JSON::ParserError)
|
|
149
|
+
# JSON.parse('{"a": 1, "a":2}', allow_duplicate_key: true) => {"a" => 2}
|
|
145
150
|
#
|
|
146
151
|
# ---
|
|
147
152
|
#
|
|
@@ -173,6 +178,42 @@ require 'json/common'
|
|
|
173
178
|
# When enabled:
|
|
174
179
|
# JSON.parse('[1,]', allow_trailing_comma: true) # => [1]
|
|
175
180
|
#
|
|
181
|
+
# ---
|
|
182
|
+
#
|
|
183
|
+
# Option +allow_comments+ (boolean) specifies whether to allow
|
|
184
|
+
# JavaScript style comments (either <tt>// comment</tt> or <tt>/* comment */</tt>);
|
|
185
|
+
# defaults to +false+.
|
|
186
|
+
#
|
|
187
|
+
# When set to +false+, the default:
|
|
188
|
+
# JSON.parse('/* comment */ {"a": 1, "a":2}') # unexpected character: '/' at line 1 column 1 (JSON::ParserError)
|
|
189
|
+
#
|
|
190
|
+
# When set to +true+, comments are ignored:
|
|
191
|
+
# JSON.parse('/* comment */ {"a": 1, "a":2} // more comment') # => {"a" => 2}
|
|
192
|
+
#
|
|
193
|
+
# ---
|
|
194
|
+
#
|
|
195
|
+
# Option +allow_control_characters+ (boolean) specifies whether to allow
|
|
196
|
+
# unescaped ASCII control characters, such as newlines, in strings;
|
|
197
|
+
# defaults to +false+.
|
|
198
|
+
#
|
|
199
|
+
# With the default, +false+:
|
|
200
|
+
# JSON.parse(%{"Hello\nWorld"}) # invalid ASCII control character in string (JSON::ParserError)
|
|
201
|
+
#
|
|
202
|
+
# When enabled:
|
|
203
|
+
# JSON.parse(%{"Hello\nWorld"}, allow_control_characters: true) # => "Hello\nWorld"
|
|
204
|
+
#
|
|
205
|
+
# ---
|
|
206
|
+
#
|
|
207
|
+
# Option +allow_invalid_escape+ (boolean) specifies whether to ignore backslahes that are followed
|
|
208
|
+
# by an invalid escape character in strings;
|
|
209
|
+
# defaults to +false+.
|
|
210
|
+
#
|
|
211
|
+
# With the default, +false+:
|
|
212
|
+
# JSON.parse('"Hell\o"') # invalid escape character in string (JSON::ParserError)
|
|
213
|
+
#
|
|
214
|
+
# When enabled:
|
|
215
|
+
# JSON.parse('"Hell\o"', allow_invalid_escape: true) # => "Hello"
|
|
216
|
+
#
|
|
176
217
|
# ====== Output Options
|
|
177
218
|
#
|
|
178
219
|
# Option +freeze+ (boolean) specifies whether the returned objects will be frozen;
|
|
@@ -218,11 +259,6 @@ require 'json/common'
|
|
|
218
259
|
# ruby = JSON.parse(source, {array_class: Set})
|
|
219
260
|
# ruby # => #<Set: {"foo", 1.0, true, false, nil}>
|
|
220
261
|
#
|
|
221
|
-
# ---
|
|
222
|
-
#
|
|
223
|
-
# Option +create_additions+ (boolean) specifies whether to use \JSON additions in parsing.
|
|
224
|
-
# See {\JSON Additions}[#module-JSON-label-JSON+Additions].
|
|
225
|
-
#
|
|
226
262
|
# === Generating \JSON
|
|
227
263
|
#
|
|
228
264
|
# To generate a Ruby \String containing \JSON data,
|
|
@@ -302,8 +338,22 @@ require 'json/common'
|
|
|
302
338
|
# JSON.generate(JSON::MinusInfinity)
|
|
303
339
|
#
|
|
304
340
|
# Allow:
|
|
305
|
-
# ruby = [Float::
|
|
306
|
-
# JSON.generate(ruby, allow_nan: true) # => '[NaN,Infinity,-Infinity]'
|
|
341
|
+
# ruby = [Float::NAN, Float::INFINITY, JSON::NaN, JSON::Infinity, JSON::MinusInfinity]
|
|
342
|
+
# JSON.generate(ruby, allow_nan: true) # => '[NaN,Infinity,NaN,Infinity,-Infinity]'
|
|
343
|
+
#
|
|
344
|
+
# ---
|
|
345
|
+
#
|
|
346
|
+
# Option +allow_duplicate_key+ (boolean) specifies whether
|
|
347
|
+
# hashes with duplicate keys should be allowed or produce an error.
|
|
348
|
+
# defaults to emit a deprecation warning.
|
|
349
|
+
#
|
|
350
|
+
# With the default, <tt>false</tt>:
|
|
351
|
+
# JSON.generate({ foo: 1, "foo" => 2 })
|
|
352
|
+
# # detected duplicate key "foo" in {foo: 1, "foo" => 2} (JSON::GeneratorError)
|
|
353
|
+
#
|
|
354
|
+
# With <tt>true</tt>
|
|
355
|
+
# JSON.generate({ foo: 1, "foo" => 2 }, allow_duplicate_key: true)
|
|
356
|
+
# # => '{"foo":1,"foo":2}'
|
|
307
357
|
#
|
|
308
358
|
# ---
|
|
309
359
|
#
|
|
@@ -318,6 +368,16 @@ require 'json/common'
|
|
|
318
368
|
# # Raises JSON::NestingError (nesting of 2 is too deep):
|
|
319
369
|
# JSON.generate(obj, max_nesting: 2)
|
|
320
370
|
#
|
|
371
|
+
# With +false+:
|
|
372
|
+
# obj = []
|
|
373
|
+
# obj[0] = obj
|
|
374
|
+
# # Raises SystemStackError: stack level too deep
|
|
375
|
+
# JSON.generate(obj, max_nesting: false)
|
|
376
|
+
#
|
|
377
|
+
# Setting +max_nesting+ to +false+ or a very large number can lead to a stack overflow
|
|
378
|
+
# which may leave the process in an unrecoverable state.
|
|
379
|
+
# It is highly discouraged.
|
|
380
|
+
#
|
|
321
381
|
# ====== Escaping Options
|
|
322
382
|
#
|
|
323
383
|
# Options +script_safe+ (boolean) specifies wether <tt>'\u2028'</tt>, <tt>'\u2029'</tt>
|
|
@@ -342,7 +402,6 @@ require 'json/common'
|
|
|
342
402
|
# to be inserted after each \JSON object; defaults to the empty \String, <tt>''</tt>.
|
|
343
403
|
# - Option +indent+ (\String) specifies the string (usually spaces) to be
|
|
344
404
|
# used for indentation; defaults to the empty \String, <tt>''</tt>;
|
|
345
|
-
# defaults to the empty \String, <tt>''</tt>;
|
|
346
405
|
# has no effect unless options +array_nl+ or +object_nl+ specify newlines.
|
|
347
406
|
# - Option +space+ (\String) specifies a string (usually a space) to be
|
|
348
407
|
# inserted after the colon in each \JSON object's pair;
|
|
@@ -350,6 +409,11 @@ require 'json/common'
|
|
|
350
409
|
# - Option +space_before+ (\String) specifies a string (usually a space) to be
|
|
351
410
|
# inserted before the colon in each \JSON object's pair;
|
|
352
411
|
# defaults to the empty \String, <tt>''</tt>.
|
|
412
|
+
# - Option +sort_keys+ (boolean or \Proc) controls whether and how the keys of a
|
|
413
|
+
# hash are sorted when generating the output; defaults to <tt>false</tt>.
|
|
414
|
+
# When +true+, keys are sorted lexicographically. When a \Proc, it receives
|
|
415
|
+
# the entire \Hash and must return a \Hash with its pairs in the desired
|
|
416
|
+
# order, allowing for arbitrary sort orders.
|
|
353
417
|
#
|
|
354
418
|
# In this example, +obj+ is used first to generate the shortest
|
|
355
419
|
# \JSON data (no whitespace), then again with all formatting options
|
|
@@ -382,238 +446,6 @@ require 'json/common'
|
|
|
382
446
|
# }
|
|
383
447
|
# }
|
|
384
448
|
#
|
|
385
|
-
# == \JSON Additions
|
|
386
|
-
#
|
|
387
|
-
# When you "round trip" a non-\String object from Ruby to \JSON and back,
|
|
388
|
-
# you have a new \String, instead of the object you began with:
|
|
389
|
-
# ruby0 = Range.new(0, 2)
|
|
390
|
-
# json = JSON.generate(ruby0)
|
|
391
|
-
# json # => '0..2"'
|
|
392
|
-
# ruby1 = JSON.parse(json)
|
|
393
|
-
# ruby1 # => '0..2'
|
|
394
|
-
# ruby1.class # => String
|
|
395
|
-
#
|
|
396
|
-
# You can use \JSON _additions_ to preserve the original object.
|
|
397
|
-
# The addition is an extension of a ruby class, so that:
|
|
398
|
-
# - \JSON.generate stores more information in the \JSON string.
|
|
399
|
-
# - \JSON.parse, called with option +create_additions+,
|
|
400
|
-
# uses that information to create a proper Ruby object.
|
|
401
|
-
#
|
|
402
|
-
# This example shows a \Range being generated into \JSON
|
|
403
|
-
# and parsed back into Ruby, both without and with
|
|
404
|
-
# the addition for \Range:
|
|
405
|
-
# ruby = Range.new(0, 2)
|
|
406
|
-
# # This passage does not use the addition for Range.
|
|
407
|
-
# json0 = JSON.generate(ruby)
|
|
408
|
-
# ruby0 = JSON.parse(json0)
|
|
409
|
-
# # This passage uses the addition for Range.
|
|
410
|
-
# require 'json/add/range'
|
|
411
|
-
# json1 = JSON.generate(ruby)
|
|
412
|
-
# ruby1 = JSON.parse(json1, create_additions: true)
|
|
413
|
-
# # Make a nice display.
|
|
414
|
-
# display = <<~EOT
|
|
415
|
-
# Generated JSON:
|
|
416
|
-
# Without addition: #{json0} (#{json0.class})
|
|
417
|
-
# With addition: #{json1} (#{json1.class})
|
|
418
|
-
# Parsed JSON:
|
|
419
|
-
# Without addition: #{ruby0.inspect} (#{ruby0.class})
|
|
420
|
-
# With addition: #{ruby1.inspect} (#{ruby1.class})
|
|
421
|
-
# EOT
|
|
422
|
-
# puts display
|
|
423
|
-
#
|
|
424
|
-
# This output shows the different results:
|
|
425
|
-
# Generated JSON:
|
|
426
|
-
# Without addition: "0..2" (String)
|
|
427
|
-
# With addition: {"json_class":"Range","a":[0,2,false]} (String)
|
|
428
|
-
# Parsed JSON:
|
|
429
|
-
# Without addition: "0..2" (String)
|
|
430
|
-
# With addition: 0..2 (Range)
|
|
431
|
-
#
|
|
432
|
-
# The \JSON module includes additions for certain classes.
|
|
433
|
-
# You can also craft custom additions.
|
|
434
|
-
# See {Custom \JSON Additions}[#module-JSON-label-Custom+JSON+Additions].
|
|
435
|
-
#
|
|
436
|
-
# === Built-in Additions
|
|
437
|
-
#
|
|
438
|
-
# The \JSON module includes additions for certain classes.
|
|
439
|
-
# To use an addition, +require+ its source:
|
|
440
|
-
# - BigDecimal: <tt>require 'json/add/bigdecimal'</tt>
|
|
441
|
-
# - Complex: <tt>require 'json/add/complex'</tt>
|
|
442
|
-
# - Date: <tt>require 'json/add/date'</tt>
|
|
443
|
-
# - DateTime: <tt>require 'json/add/date_time'</tt>
|
|
444
|
-
# - Exception: <tt>require 'json/add/exception'</tt>
|
|
445
|
-
# - OpenStruct: <tt>require 'json/add/ostruct'</tt>
|
|
446
|
-
# - Range: <tt>require 'json/add/range'</tt>
|
|
447
|
-
# - Rational: <tt>require 'json/add/rational'</tt>
|
|
448
|
-
# - Regexp: <tt>require 'json/add/regexp'</tt>
|
|
449
|
-
# - Set: <tt>require 'json/add/set'</tt>
|
|
450
|
-
# - Struct: <tt>require 'json/add/struct'</tt>
|
|
451
|
-
# - Symbol: <tt>require 'json/add/symbol'</tt>
|
|
452
|
-
# - Time: <tt>require 'json/add/time'</tt>
|
|
453
|
-
#
|
|
454
|
-
# To reduce punctuation clutter, the examples below
|
|
455
|
-
# show the generated \JSON via +puts+, rather than the usual +inspect+,
|
|
456
|
-
#
|
|
457
|
-
# \BigDecimal:
|
|
458
|
-
# require 'json/add/bigdecimal'
|
|
459
|
-
# ruby0 = BigDecimal(0) # 0.0
|
|
460
|
-
# json = JSON.generate(ruby0) # {"json_class":"BigDecimal","b":"27:0.0"}
|
|
461
|
-
# ruby1 = JSON.parse(json, create_additions: true) # 0.0
|
|
462
|
-
# ruby1.class # => BigDecimal
|
|
463
|
-
#
|
|
464
|
-
# \Complex:
|
|
465
|
-
# require 'json/add/complex'
|
|
466
|
-
# ruby0 = Complex(1+0i) # 1+0i
|
|
467
|
-
# json = JSON.generate(ruby0) # {"json_class":"Complex","r":1,"i":0}
|
|
468
|
-
# ruby1 = JSON.parse(json, create_additions: true) # 1+0i
|
|
469
|
-
# ruby1.class # Complex
|
|
470
|
-
#
|
|
471
|
-
# \Date:
|
|
472
|
-
# require 'json/add/date'
|
|
473
|
-
# ruby0 = Date.today # 2020-05-02
|
|
474
|
-
# json = JSON.generate(ruby0) # {"json_class":"Date","y":2020,"m":5,"d":2,"sg":2299161.0}
|
|
475
|
-
# ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02
|
|
476
|
-
# ruby1.class # Date
|
|
477
|
-
#
|
|
478
|
-
# \DateTime:
|
|
479
|
-
# require 'json/add/date_time'
|
|
480
|
-
# ruby0 = DateTime.now # 2020-05-02T10:38:13-05:00
|
|
481
|
-
# json = JSON.generate(ruby0) # {"json_class":"DateTime","y":2020,"m":5,"d":2,"H":10,"M":38,"S":13,"of":"-5/24","sg":2299161.0}
|
|
482
|
-
# ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02T10:38:13-05:00
|
|
483
|
-
# ruby1.class # DateTime
|
|
484
|
-
#
|
|
485
|
-
# \Exception (and its subclasses including \RuntimeError):
|
|
486
|
-
# require 'json/add/exception'
|
|
487
|
-
# ruby0 = Exception.new('A message') # A message
|
|
488
|
-
# json = JSON.generate(ruby0) # {"json_class":"Exception","m":"A message","b":null}
|
|
489
|
-
# ruby1 = JSON.parse(json, create_additions: true) # A message
|
|
490
|
-
# ruby1.class # Exception
|
|
491
|
-
# ruby0 = RuntimeError.new('Another message') # Another message
|
|
492
|
-
# json = JSON.generate(ruby0) # {"json_class":"RuntimeError","m":"Another message","b":null}
|
|
493
|
-
# ruby1 = JSON.parse(json, create_additions: true) # Another message
|
|
494
|
-
# ruby1.class # RuntimeError
|
|
495
|
-
#
|
|
496
|
-
# \OpenStruct:
|
|
497
|
-
# require 'json/add/ostruct'
|
|
498
|
-
# ruby0 = OpenStruct.new(name: 'Matz', language: 'Ruby') # #<OpenStruct name="Matz", language="Ruby">
|
|
499
|
-
# json = JSON.generate(ruby0) # {"json_class":"OpenStruct","t":{"name":"Matz","language":"Ruby"}}
|
|
500
|
-
# ruby1 = JSON.parse(json, create_additions: true) # #<OpenStruct name="Matz", language="Ruby">
|
|
501
|
-
# ruby1.class # OpenStruct
|
|
502
|
-
#
|
|
503
|
-
# \Range:
|
|
504
|
-
# require 'json/add/range'
|
|
505
|
-
# ruby0 = Range.new(0, 2) # 0..2
|
|
506
|
-
# json = JSON.generate(ruby0) # {"json_class":"Range","a":[0,2,false]}
|
|
507
|
-
# ruby1 = JSON.parse(json, create_additions: true) # 0..2
|
|
508
|
-
# ruby1.class # Range
|
|
509
|
-
#
|
|
510
|
-
# \Rational:
|
|
511
|
-
# require 'json/add/rational'
|
|
512
|
-
# ruby0 = Rational(1, 3) # 1/3
|
|
513
|
-
# json = JSON.generate(ruby0) # {"json_class":"Rational","n":1,"d":3}
|
|
514
|
-
# ruby1 = JSON.parse(json, create_additions: true) # 1/3
|
|
515
|
-
# ruby1.class # Rational
|
|
516
|
-
#
|
|
517
|
-
# \Regexp:
|
|
518
|
-
# require 'json/add/regexp'
|
|
519
|
-
# ruby0 = Regexp.new('foo') # (?-mix:foo)
|
|
520
|
-
# json = JSON.generate(ruby0) # {"json_class":"Regexp","o":0,"s":"foo"}
|
|
521
|
-
# ruby1 = JSON.parse(json, create_additions: true) # (?-mix:foo)
|
|
522
|
-
# ruby1.class # Regexp
|
|
523
|
-
#
|
|
524
|
-
# \Set:
|
|
525
|
-
# require 'json/add/set'
|
|
526
|
-
# ruby0 = Set.new([0, 1, 2]) # #<Set: {0, 1, 2}>
|
|
527
|
-
# json = JSON.generate(ruby0) # {"json_class":"Set","a":[0,1,2]}
|
|
528
|
-
# ruby1 = JSON.parse(json, create_additions: true) # #<Set: {0, 1, 2}>
|
|
529
|
-
# ruby1.class # Set
|
|
530
|
-
#
|
|
531
|
-
# \Struct:
|
|
532
|
-
# require 'json/add/struct'
|
|
533
|
-
# Customer = Struct.new(:name, :address) # Customer
|
|
534
|
-
# ruby0 = Customer.new("Dave", "123 Main") # #<struct Customer name="Dave", address="123 Main">
|
|
535
|
-
# json = JSON.generate(ruby0) # {"json_class":"Customer","v":["Dave","123 Main"]}
|
|
536
|
-
# ruby1 = JSON.parse(json, create_additions: true) # #<struct Customer name="Dave", address="123 Main">
|
|
537
|
-
# ruby1.class # Customer
|
|
538
|
-
#
|
|
539
|
-
# \Symbol:
|
|
540
|
-
# require 'json/add/symbol'
|
|
541
|
-
# ruby0 = :foo # foo
|
|
542
|
-
# json = JSON.generate(ruby0) # {"json_class":"Symbol","s":"foo"}
|
|
543
|
-
# ruby1 = JSON.parse(json, create_additions: true) # foo
|
|
544
|
-
# ruby1.class # Symbol
|
|
545
|
-
#
|
|
546
|
-
# \Time:
|
|
547
|
-
# require 'json/add/time'
|
|
548
|
-
# ruby0 = Time.now # 2020-05-02 11:28:26 -0500
|
|
549
|
-
# json = JSON.generate(ruby0) # {"json_class":"Time","s":1588436906,"n":840560000}
|
|
550
|
-
# ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02 11:28:26 -0500
|
|
551
|
-
# ruby1.class # Time
|
|
552
|
-
#
|
|
553
|
-
#
|
|
554
|
-
# === Custom \JSON Additions
|
|
555
|
-
#
|
|
556
|
-
# In addition to the \JSON additions provided,
|
|
557
|
-
# you can craft \JSON additions of your own,
|
|
558
|
-
# either for Ruby built-in classes or for user-defined classes.
|
|
559
|
-
#
|
|
560
|
-
# Here's a user-defined class +Foo+:
|
|
561
|
-
# class Foo
|
|
562
|
-
# attr_accessor :bar, :baz
|
|
563
|
-
# def initialize(bar, baz)
|
|
564
|
-
# self.bar = bar
|
|
565
|
-
# self.baz = baz
|
|
566
|
-
# end
|
|
567
|
-
# end
|
|
568
|
-
#
|
|
569
|
-
# Here's the \JSON addition for it:
|
|
570
|
-
# # Extend class Foo with JSON addition.
|
|
571
|
-
# class Foo
|
|
572
|
-
# # Serialize Foo object with its class name and arguments
|
|
573
|
-
# def to_json(*args)
|
|
574
|
-
# {
|
|
575
|
-
# JSON.create_id => self.class.name,
|
|
576
|
-
# 'a' => [ bar, baz ]
|
|
577
|
-
# }.to_json(*args)
|
|
578
|
-
# end
|
|
579
|
-
# # Deserialize JSON string by constructing new Foo object with arguments.
|
|
580
|
-
# def self.json_create(object)
|
|
581
|
-
# new(*object['a'])
|
|
582
|
-
# end
|
|
583
|
-
# end
|
|
584
|
-
#
|
|
585
|
-
# Demonstration:
|
|
586
|
-
# require 'json'
|
|
587
|
-
# # This Foo object has no custom addition.
|
|
588
|
-
# foo0 = Foo.new(0, 1)
|
|
589
|
-
# json0 = JSON.generate(foo0)
|
|
590
|
-
# obj0 = JSON.parse(json0)
|
|
591
|
-
# # Lood the custom addition.
|
|
592
|
-
# require_relative 'foo_addition'
|
|
593
|
-
# # This foo has the custom addition.
|
|
594
|
-
# foo1 = Foo.new(0, 1)
|
|
595
|
-
# json1 = JSON.generate(foo1)
|
|
596
|
-
# obj1 = JSON.parse(json1, create_additions: true)
|
|
597
|
-
# # Make a nice display.
|
|
598
|
-
# display = <<~EOT
|
|
599
|
-
# Generated JSON:
|
|
600
|
-
# Without custom addition: #{json0} (#{json0.class})
|
|
601
|
-
# With custom addition: #{json1} (#{json1.class})
|
|
602
|
-
# Parsed JSON:
|
|
603
|
-
# Without custom addition: #{obj0.inspect} (#{obj0.class})
|
|
604
|
-
# With custom addition: #{obj1.inspect} (#{obj1.class})
|
|
605
|
-
# EOT
|
|
606
|
-
# puts display
|
|
607
|
-
#
|
|
608
|
-
# Output:
|
|
609
|
-
#
|
|
610
|
-
# Generated JSON:
|
|
611
|
-
# Without custom addition: "#<Foo:0x0000000006534e80>" (String)
|
|
612
|
-
# With custom addition: {"json_class":"Foo","a":[0,1]} (String)
|
|
613
|
-
# Parsed JSON:
|
|
614
|
-
# Without custom addition: "#<Foo:0x0000000006534e80>" (String)
|
|
615
|
-
# With custom addition: #<Foo:0x0000000006473bb8 @bar=0, @baz=1> (Foo)
|
|
616
|
-
#
|
|
617
449
|
module JSON
|
|
618
450
|
require 'json/version'
|
|
619
451
|
require 'json/ext'
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: json
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 3.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Florian Frank
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies: []
|
|
12
12
|
description: This is a JSON implementation as a Ruby extension in C.
|
|
13
13
|
email: flori@ping.de
|
|
@@ -26,32 +26,19 @@ files:
|
|
|
26
26
|
- ext/json/ext/fbuffer/fbuffer.h
|
|
27
27
|
- ext/json/ext/generator/extconf.rb
|
|
28
28
|
- ext/json/ext/generator/generator.c
|
|
29
|
+
- ext/json/ext/json.h
|
|
29
30
|
- ext/json/ext/parser/extconf.rb
|
|
30
31
|
- ext/json/ext/parser/parser.c
|
|
31
32
|
- ext/json/ext/simd/conf.rb
|
|
32
33
|
- ext/json/ext/simd/simd.h
|
|
34
|
+
- ext/json/ext/vendor/fast_float_parser.h
|
|
33
35
|
- ext/json/ext/vendor/fpconv.c
|
|
34
36
|
- ext/json/ext/vendor/jeaiii-ltoa.h
|
|
35
37
|
- json.gemspec
|
|
36
38
|
- lib/json.rb
|
|
37
|
-
- lib/json/add/bigdecimal.rb
|
|
38
|
-
- lib/json/add/complex.rb
|
|
39
|
-
- lib/json/add/core.rb
|
|
40
|
-
- lib/json/add/date.rb
|
|
41
|
-
- lib/json/add/date_time.rb
|
|
42
|
-
- lib/json/add/exception.rb
|
|
43
|
-
- lib/json/add/ostruct.rb
|
|
44
|
-
- lib/json/add/range.rb
|
|
45
|
-
- lib/json/add/rational.rb
|
|
46
|
-
- lib/json/add/regexp.rb
|
|
47
|
-
- lib/json/add/set.rb
|
|
48
|
-
- lib/json/add/struct.rb
|
|
49
|
-
- lib/json/add/symbol.rb
|
|
50
|
-
- lib/json/add/time.rb
|
|
51
39
|
- lib/json/common.rb
|
|
52
40
|
- lib/json/ext.rb
|
|
53
41
|
- lib/json/ext/generator/state.rb
|
|
54
|
-
- lib/json/generic_object.rb
|
|
55
42
|
- lib/json/truffle_ruby/generator.rb
|
|
56
43
|
- lib/json/version.rb
|
|
57
44
|
homepage: https://github.com/ruby/json
|
|
@@ -81,7 +68,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
81
68
|
- !ruby/object:Gem::Version
|
|
82
69
|
version: '0'
|
|
83
70
|
requirements: []
|
|
84
|
-
rubygems_version:
|
|
71
|
+
rubygems_version: 4.0.16
|
|
85
72
|
specification_version: 4
|
|
86
73
|
summary: JSON Implementation for Ruby
|
|
87
74
|
test_files: []
|
data/lib/json/add/bigdecimal.rb
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
|
|
3
|
-
require 'json'
|
|
4
|
-
end
|
|
5
|
-
begin
|
|
6
|
-
require 'bigdecimal'
|
|
7
|
-
rescue LoadError
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
class BigDecimal
|
|
11
|
-
|
|
12
|
-
# See #as_json.
|
|
13
|
-
def self.json_create(object)
|
|
14
|
-
BigDecimal._load object['b']
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
# Methods <tt>BigDecimal#as_json</tt> and +BigDecimal.json_create+ may be used
|
|
18
|
-
# to serialize and deserialize a \BigDecimal object;
|
|
19
|
-
# see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html].
|
|
20
|
-
#
|
|
21
|
-
# \Method <tt>BigDecimal#as_json</tt> serializes +self+,
|
|
22
|
-
# returning a 2-element hash representing +self+:
|
|
23
|
-
#
|
|
24
|
-
# require 'json/add/bigdecimal'
|
|
25
|
-
# x = BigDecimal(2).as_json # => {"json_class"=>"BigDecimal", "b"=>"27:0.2e1"}
|
|
26
|
-
# y = BigDecimal(2.0, 4).as_json # => {"json_class"=>"BigDecimal", "b"=>"36:0.2e1"}
|
|
27
|
-
# z = BigDecimal(Complex(2, 0)).as_json # => {"json_class"=>"BigDecimal", "b"=>"27:0.2e1"}
|
|
28
|
-
#
|
|
29
|
-
# \Method +JSON.create+ deserializes such a hash, returning a \BigDecimal object:
|
|
30
|
-
#
|
|
31
|
-
# BigDecimal.json_create(x) # => 0.2e1
|
|
32
|
-
# BigDecimal.json_create(y) # => 0.2e1
|
|
33
|
-
# BigDecimal.json_create(z) # => 0.2e1
|
|
34
|
-
#
|
|
35
|
-
def as_json(*)
|
|
36
|
-
{
|
|
37
|
-
JSON.create_id => self.class.name,
|
|
38
|
-
'b' => _dump.force_encoding(Encoding::UTF_8),
|
|
39
|
-
}
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
# Returns a JSON string representing +self+:
|
|
43
|
-
#
|
|
44
|
-
# require 'json/add/bigdecimal'
|
|
45
|
-
# puts BigDecimal(2).to_json
|
|
46
|
-
# puts BigDecimal(2.0, 4).to_json
|
|
47
|
-
# puts BigDecimal(Complex(2, 0)).to_json
|
|
48
|
-
#
|
|
49
|
-
# Output:
|
|
50
|
-
#
|
|
51
|
-
# {"json_class":"BigDecimal","b":"27:0.2e1"}
|
|
52
|
-
# {"json_class":"BigDecimal","b":"36:0.2e1"}
|
|
53
|
-
# {"json_class":"BigDecimal","b":"27:0.2e1"}
|
|
54
|
-
#
|
|
55
|
-
def to_json(*args)
|
|
56
|
-
as_json.to_json(*args)
|
|
57
|
-
end
|
|
58
|
-
end if defined?(::BigDecimal)
|
data/lib/json/add/complex.rb
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
|
|
3
|
-
require 'json'
|
|
4
|
-
end
|
|
5
|
-
|
|
6
|
-
class Complex
|
|
7
|
-
|
|
8
|
-
# See #as_json.
|
|
9
|
-
def self.json_create(object)
|
|
10
|
-
Complex(object['r'], object['i'])
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
# Methods <tt>Complex#as_json</tt> and +Complex.json_create+ may be used
|
|
14
|
-
# to serialize and deserialize a \Complex object;
|
|
15
|
-
# see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html].
|
|
16
|
-
#
|
|
17
|
-
# \Method <tt>Complex#as_json</tt> serializes +self+,
|
|
18
|
-
# returning a 2-element hash representing +self+:
|
|
19
|
-
#
|
|
20
|
-
# require 'json/add/complex'
|
|
21
|
-
# x = Complex(2).as_json # => {"json_class"=>"Complex", "r"=>2, "i"=>0}
|
|
22
|
-
# y = Complex(2.0, 4).as_json # => {"json_class"=>"Complex", "r"=>2.0, "i"=>4}
|
|
23
|
-
#
|
|
24
|
-
# \Method +JSON.create+ deserializes such a hash, returning a \Complex object:
|
|
25
|
-
#
|
|
26
|
-
# Complex.json_create(x) # => (2+0i)
|
|
27
|
-
# Complex.json_create(y) # => (2.0+4i)
|
|
28
|
-
#
|
|
29
|
-
def as_json(*)
|
|
30
|
-
{
|
|
31
|
-
JSON.create_id => self.class.name,
|
|
32
|
-
'r' => real,
|
|
33
|
-
'i' => imag,
|
|
34
|
-
}
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# Returns a JSON string representing +self+:
|
|
38
|
-
#
|
|
39
|
-
# require 'json/add/complex'
|
|
40
|
-
# puts Complex(2).to_json
|
|
41
|
-
# puts Complex(2.0, 4).to_json
|
|
42
|
-
#
|
|
43
|
-
# Output:
|
|
44
|
-
#
|
|
45
|
-
# {"json_class":"Complex","r":2,"i":0}
|
|
46
|
-
# {"json_class":"Complex","r":2.0,"i":4}
|
|
47
|
-
#
|
|
48
|
-
def to_json(*args)
|
|
49
|
-
as_json.to_json(*args)
|
|
50
|
-
end
|
|
51
|
-
end
|
data/lib/json/add/core.rb
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
# This file requires the implementations of ruby core's custom objects for
|
|
3
|
-
# serialisation/deserialisation.
|
|
4
|
-
|
|
5
|
-
require 'json/add/date'
|
|
6
|
-
require 'json/add/date_time'
|
|
7
|
-
require 'json/add/exception'
|
|
8
|
-
require 'json/add/range'
|
|
9
|
-
require 'json/add/regexp'
|
|
10
|
-
require 'json/add/struct'
|
|
11
|
-
require 'json/add/symbol'
|
|
12
|
-
require 'json/add/time'
|
data/lib/json/add/date.rb
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
|
|
3
|
-
require 'json'
|
|
4
|
-
end
|
|
5
|
-
require 'date'
|
|
6
|
-
|
|
7
|
-
class Date
|
|
8
|
-
|
|
9
|
-
# See #as_json.
|
|
10
|
-
def self.json_create(object)
|
|
11
|
-
civil(*object.values_at('y', 'm', 'd', 'sg'))
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
alias start sg unless method_defined?(:start)
|
|
15
|
-
|
|
16
|
-
# Methods <tt>Date#as_json</tt> and +Date.json_create+ may be used
|
|
17
|
-
# to serialize and deserialize a \Date object;
|
|
18
|
-
# see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html].
|
|
19
|
-
#
|
|
20
|
-
# \Method <tt>Date#as_json</tt> serializes +self+,
|
|
21
|
-
# returning a 2-element hash representing +self+:
|
|
22
|
-
#
|
|
23
|
-
# require 'json/add/date'
|
|
24
|
-
# x = Date.today.as_json
|
|
25
|
-
# # => {"json_class"=>"Date", "y"=>2023, "m"=>11, "d"=>21, "sg"=>2299161.0}
|
|
26
|
-
#
|
|
27
|
-
# \Method +JSON.create+ deserializes such a hash, returning a \Date object:
|
|
28
|
-
#
|
|
29
|
-
# Date.json_create(x)
|
|
30
|
-
# # => #<Date: 2023-11-21 ((2460270j,0s,0n),+0s,2299161j)>
|
|
31
|
-
#
|
|
32
|
-
def as_json(*)
|
|
33
|
-
{
|
|
34
|
-
JSON.create_id => self.class.name,
|
|
35
|
-
'y' => year,
|
|
36
|
-
'm' => month,
|
|
37
|
-
'd' => day,
|
|
38
|
-
'sg' => start,
|
|
39
|
-
}
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
# Returns a JSON string representing +self+:
|
|
43
|
-
#
|
|
44
|
-
# require 'json/add/date'
|
|
45
|
-
# puts Date.today.to_json
|
|
46
|
-
#
|
|
47
|
-
# Output:
|
|
48
|
-
#
|
|
49
|
-
# {"json_class":"Date","y":2023,"m":11,"d":21,"sg":2299161.0}
|
|
50
|
-
#
|
|
51
|
-
def to_json(*args)
|
|
52
|
-
as_json.to_json(*args)
|
|
53
|
-
end
|
|
54
|
-
end
|