json_pure 2.1.0 → 2.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/CHANGES.md +50 -0
- data/Gemfile +0 -2
- data/LICENSE +56 -0
- data/README.md +54 -21
- data/VERSION +1 -1
- data/json_pure.gemspec +49 -26
- data/lib/json.rb +549 -29
- data/lib/json/add/bigdecimal.rb +2 -2
- data/lib/json/add/complex.rb +2 -3
- data/lib/json/add/ostruct.rb +1 -1
- data/lib/json/add/rational.rb +2 -3
- data/lib/json/add/regexp.rb +2 -2
- data/lib/json/add/set.rb +29 -0
- data/lib/json/common.rb +341 -115
- data/lib/json/pure/generator.rb +31 -10
- data/lib/json/pure/parser.rb +31 -5
- data/lib/json/version.rb +1 -1
- data/tests/fixtures/fail29.json +1 -0
- data/tests/fixtures/fail30.json +1 -0
- data/tests/fixtures/fail31.json +1 -0
- data/tests/fixtures/fail32.json +1 -0
- data/tests/json_addition_test.rb +6 -0
- data/tests/json_common_interface_test.rb +47 -4
- data/tests/json_fixtures_test.rb +9 -1
- data/tests/json_generator_test.rb +55 -0
- data/tests/json_parser_test.rb +40 -14
- data/tests/test_helper.rb +3 -7
- metadata +24 -52
- data/.gitignore +0 -17
- data/.travis.yml +0 -19
- data/README-json-jruby.md +0 -33
- data/Rakefile +0 -408
- data/data/example.json +0 -1
- data/data/index.html +0 -38
- data/data/prototype.js +0 -4184
- data/diagrams/.keep +0 -0
- data/ext/json/ext/fbuffer/fbuffer.h +0 -187
- data/ext/json/ext/generator/depend +0 -1
- data/ext/json/ext/generator/extconf.rb +0 -4
- data/ext/json/ext/generator/generator.c +0 -1443
- data/ext/json/ext/generator/generator.h +0 -171
- data/ext/json/ext/parser/depend +0 -1
- data/ext/json/ext/parser/extconf.rb +0 -6
- data/ext/json/ext/parser/parser.c +0 -2109
- data/ext/json/ext/parser/parser.h +0 -91
- data/ext/json/ext/parser/parser.rl +0 -869
- data/ext/json/extconf.rb +0 -2
- data/install.rb +0 -23
- data/java/src/json/ext/ByteListTranscoder.java +0 -166
- data/java/src/json/ext/Generator.java +0 -443
- data/java/src/json/ext/GeneratorMethods.java +0 -231
- data/java/src/json/ext/GeneratorService.java +0 -42
- data/java/src/json/ext/GeneratorState.java +0 -490
- data/java/src/json/ext/OptionsReader.java +0 -113
- data/java/src/json/ext/Parser.java +0 -2362
- data/java/src/json/ext/Parser.rl +0 -893
- data/java/src/json/ext/ParserService.java +0 -34
- data/java/src/json/ext/RuntimeInfo.java +0 -116
- data/java/src/json/ext/StringDecoder.java +0 -166
- data/java/src/json/ext/StringEncoder.java +0 -111
- data/java/src/json/ext/Utils.java +0 -88
- data/json-java.gemspec +0 -38
- data/json.gemspec +0 -0
- data/references/rfc7159.txt +0 -899
- data/tools/diff.sh +0 -18
- data/tools/fuzz.rb +0 -131
- data/tools/server.rb +0 -62
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ccaf5d00b6462faaa558a21e868626904f051a833eea93e81e2ae2e3cdc9dfd0
|
4
|
+
data.tar.gz: 63d055fcb71de6f94d7c2632aba540f5450631a96813a7eee962939a0957b43d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7f40f310a0c21b71b936caa11fa219f24a746719d4e7f10c07a2dc7747a741943344a639ad21b404964413d00fe3f9a74c97e936d3fe82a1a36c23aae522724e
|
7
|
+
data.tar.gz: 53cc02a7433b9d08cd7f6ba48bce2de608c8daac160e662fa8cf14d65173b9402527390a521aa90a1679fb0ee67f4e9a25b1e3cf4baeb7765c7adc12439f13fc
|
data/CHANGES.md
CHANGED
@@ -1,5 +1,55 @@
|
|
1
1
|
# Changes
|
2
2
|
|
3
|
+
## 2020-12-17 (2.4.1)
|
4
|
+
|
5
|
+
* Restore version.rb with 2.4.1
|
6
|
+
|
7
|
+
## 2020-12-15 (2.4.0)
|
8
|
+
|
9
|
+
* Implement a freeze: parser option #447
|
10
|
+
* Fix an issue with generate_pretty and empty objects in the Ruby and Java implementations #449
|
11
|
+
* Fix JSON.load_file doc #448
|
12
|
+
* Fix pure parser with unclosed arrays / objects #425
|
13
|
+
* bundle the LICENSE file in the gem #444
|
14
|
+
* Add an option to escape forward slash character #405
|
15
|
+
* RDoc for JSON #439 #446 #442 #434 #433 #430
|
16
|
+
|
17
|
+
## 2020-06-30 (2.3.1)
|
18
|
+
|
19
|
+
* Spelling and grammar fixes for comments. Pull request #191 by Josh
|
20
|
+
Kline.
|
21
|
+
* Enhance generic JSON and #generate docs. Pull request #347 by Victor
|
22
|
+
Shepelev.
|
23
|
+
* Add :nodoc: for GeneratorMethods. Pull request #349 by Victor Shepelev.
|
24
|
+
* Baseline changes to help (JRuby) development. Pull request #371 by Karol
|
25
|
+
Bucek.
|
26
|
+
* Add metadata for rubygems.org. Pull request #379 by Alexandre ZANNI.
|
27
|
+
* Remove invalid JSON.generate description from JSON module rdoc. Pull
|
28
|
+
request #384 by Jeremy Evans.
|
29
|
+
* Test with TruffleRuby in CI. Pull request #402 by Benoit Daloze.
|
30
|
+
* Rdoc enhancements. Pull request #413 by Burdette Lamar.
|
31
|
+
* Fixtures/ are not being tested... Pull request #416 by Marc-André
|
32
|
+
Lafortune.
|
33
|
+
* Use frozen string for hash key. Pull request #420 by Marc-André
|
34
|
+
Lafortune.
|
35
|
+
* Added :call-seq: to RDoc for some methods. Pull request #422 by Burdette
|
36
|
+
Lamar.
|
37
|
+
* Small typo fix. Pull request #423 by Marc-André Lafortune.
|
38
|
+
|
39
|
+
## 2019-12-11 (2.3.0)
|
40
|
+
* Fix default of `create_additions` to always be `false` for `JSON(user_input)`
|
41
|
+
and `JSON.parse(user_input, nil)`.
|
42
|
+
Note that `JSON.load` remains with default `true` and is meant for internal
|
43
|
+
serialization of trusted data. [CVE-2020-10663]
|
44
|
+
* Fix passing args all #to_json in json/add/*.
|
45
|
+
* Fix encoding issues
|
46
|
+
* Fix issues of keyword vs positional parameter
|
47
|
+
* Fix JSON::Parser against bigdecimal updates
|
48
|
+
* Bug fixes to JRuby port
|
49
|
+
|
50
|
+
## 2019-02-21 (2.2.0)
|
51
|
+
* Adds support for 2.6 BigDecimal and ruby standard library Set datetype.
|
52
|
+
|
3
53
|
## 2017-04-18 (2.1.0)
|
4
54
|
* Allow passing of `decimal_class` option to specify a class as which to parse
|
5
55
|
JSON float numbers.
|
data/Gemfile
CHANGED
data/LICENSE
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.jp>.
|
2
|
+
You can redistribute it and/or modify it under either the terms of the
|
3
|
+
2-clause BSDL (see the file BSDL), or the conditions below:
|
4
|
+
|
5
|
+
1. You may make and give away verbatim copies of the source form of the
|
6
|
+
software without restriction, provided that you duplicate all of the
|
7
|
+
original copyright notices and associated disclaimers.
|
8
|
+
|
9
|
+
2. You may modify your copy of the software in any way, provided that
|
10
|
+
you do at least ONE of the following:
|
11
|
+
|
12
|
+
a) place your modifications in the Public Domain or otherwise
|
13
|
+
make them Freely Available, such as by posting said
|
14
|
+
modifications to Usenet or an equivalent medium, or by allowing
|
15
|
+
the author to include your modifications in the software.
|
16
|
+
|
17
|
+
b) use the modified software only within your corporation or
|
18
|
+
organization.
|
19
|
+
|
20
|
+
c) give non-standard binaries non-standard names, with
|
21
|
+
instructions on where to get the original software distribution.
|
22
|
+
|
23
|
+
d) make other distribution arrangements with the author.
|
24
|
+
|
25
|
+
3. You may distribute the software in object code or binary form,
|
26
|
+
provided that you do at least ONE of the following:
|
27
|
+
|
28
|
+
a) distribute the binaries and library files of the software,
|
29
|
+
together with instructions (in the manual page or equivalent)
|
30
|
+
on where to get the original distribution.
|
31
|
+
|
32
|
+
b) accompany the distribution with the machine-readable source of
|
33
|
+
the software.
|
34
|
+
|
35
|
+
c) give non-standard binaries non-standard names, with
|
36
|
+
instructions on where to get the original software distribution.
|
37
|
+
|
38
|
+
d) make other distribution arrangements with the author.
|
39
|
+
|
40
|
+
4. You may modify and include the part of the software into any other
|
41
|
+
software (possibly commercial). But some files in the distribution
|
42
|
+
are not written by the author, so that they are not under these terms.
|
43
|
+
|
44
|
+
For the list of those files and their copying conditions, see the
|
45
|
+
file LEGAL.
|
46
|
+
|
47
|
+
5. The scripts and library files supplied as input to or produced as
|
48
|
+
output from the software do not automatically fall under the
|
49
|
+
copyright of the software, but belong to whomever generated them,
|
50
|
+
and may be sold commercially, and may be aggregated with this
|
51
|
+
software.
|
52
|
+
|
53
|
+
6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
|
54
|
+
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
55
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
56
|
+
PURPOSE.
|
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
# JSON implementation for Ruby
|
2
|
-
|
1
|
+
# JSON implementation for Ruby
|
2
|
+
|
3
|
+
[](https://travis-ci.org/flori/json)
|
3
4
|
|
4
5
|
## Description
|
5
6
|
|
@@ -150,6 +151,18 @@ require 'json/add/rails'
|
|
150
151
|
Both of the additions attempt to require `'json'` (like above) first, if it has
|
151
152
|
not been required yet.
|
152
153
|
|
154
|
+
## Serializing exceptions
|
155
|
+
|
156
|
+
The JSON module doesn't extend `Exception` by default. If you convert an `Exception`
|
157
|
+
object to JSON, it will by default only include the exception message.
|
158
|
+
|
159
|
+
To include the full details, you must either load the `json/add/core` mentioned
|
160
|
+
above, or specifically load the exception addition:
|
161
|
+
|
162
|
+
```ruby
|
163
|
+
require 'json/add/exception'
|
164
|
+
```
|
165
|
+
|
153
166
|
## More Examples
|
154
167
|
|
155
168
|
To create a JSON document from a ruby data structure, you can call
|
@@ -179,14 +192,14 @@ should return a JSON object (a hash converted to JSON with `#to_json`) like
|
|
179
192
|
this (don't forget the `*a` for all the arguments):
|
180
193
|
|
181
194
|
```ruby
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
195
|
+
class Range
|
196
|
+
def to_json(*a)
|
197
|
+
{
|
198
|
+
'json_class' => self.class.name, # = 'Range'
|
199
|
+
'data' => [ first, last, exclude_end? ]
|
200
|
+
}.to_json(*a)
|
201
|
+
end
|
202
|
+
end
|
190
203
|
```
|
191
204
|
|
192
205
|
The hash key `json_class` is the class, that will be asked to deserialise the
|
@@ -194,26 +207,30 @@ JSON representation later. In this case it's `Range`, but any namespace of
|
|
194
207
|
the form `A::B` or `::A::B` will do. All other keys are arbitrary and can be
|
195
208
|
used to store the necessary data to configure the object to be deserialised.
|
196
209
|
|
197
|
-
If
|
210
|
+
If the key `json_class` is found in a JSON object, the JSON parser checks
|
198
211
|
if the given class responds to the `json_create` class method. If so, it is
|
199
212
|
called with the JSON object converted to a Ruby hash. So a range can
|
200
213
|
be deserialised by implementing `Range.json_create` like this:
|
201
214
|
|
202
215
|
```ruby
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
216
|
+
class Range
|
217
|
+
def self.json_create(o)
|
218
|
+
new(*o['data'])
|
219
|
+
end
|
220
|
+
end
|
208
221
|
```
|
209
222
|
|
210
223
|
Now it possible to serialise/deserialise ranges as well:
|
211
224
|
|
212
225
|
```ruby
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
226
|
+
json = JSON.generate [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
|
227
|
+
# => "[1,2,{\"a\":3.141},false,true,null,{\"json_class\":\"Range\",\"data\":[4,10,false]}]"
|
228
|
+
JSON.parse json
|
229
|
+
# => [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
|
230
|
+
json = JSON.generate [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
|
231
|
+
# => "[1,2,{\"a\":3.141},false,true,null,{\"json_class\":\"Range\",\"data\":[4,10,false]}]"
|
232
|
+
JSON.parse json, :create_additions => true
|
233
|
+
# => [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
|
217
234
|
```
|
218
235
|
|
219
236
|
`JSON.generate` always creates the shortest possible string representation of a
|
@@ -373,6 +390,22 @@ Here are the median comparisons for completeness' sake:
|
|
373
390
|
secs/call
|
374
391
|
```
|
375
392
|
|
393
|
+
## Development
|
394
|
+
|
395
|
+
### Release
|
396
|
+
|
397
|
+
Update the json.gemspec and json-java.gemspec.
|
398
|
+
|
399
|
+
```
|
400
|
+
rbenv shell 2.6.5
|
401
|
+
rake build
|
402
|
+
gem push pkg/json-2.3.0.gem
|
403
|
+
|
404
|
+
rbenv shell jruby-9.2.9.0
|
405
|
+
rake build
|
406
|
+
gem push pkg/json-2.3.0-java.gem
|
407
|
+
```
|
408
|
+
|
376
409
|
## Author
|
377
410
|
|
378
411
|
Florian Frank <mailto:flori@ping.de>
|
@@ -389,4 +422,4 @@ The latest version of this library can be downloaded at
|
|
389
422
|
|
390
423
|
Online Documentation should be located at
|
391
424
|
|
392
|
-
*
|
425
|
+
* https://www.rubydoc.info/gems/json
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.1
|
1
|
+
2.4.1
|
data/json_pure.gemspec
CHANGED
@@ -1,38 +1,61 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
# stub: json_pure 2.1.0 ruby lib
|
3
2
|
|
4
3
|
Gem::Specification.new do |s|
|
5
4
|
s.name = "json_pure".freeze
|
6
|
-
s.version = "
|
5
|
+
s.version = File.read("VERSION").chomp
|
7
6
|
|
8
|
-
s.
|
9
|
-
s.require_paths = ["lib".freeze]
|
10
|
-
s.authors = ["Florian Frank".freeze]
|
11
|
-
s.date = "2017-04-18"
|
7
|
+
s.summary = "JSON Implementation for Ruby".freeze
|
12
8
|
s.description = "This is a JSON implementation in pure Ruby.".freeze
|
9
|
+
s.licenses = ["Ruby".freeze]
|
10
|
+
s.authors = ["Florian Frank".freeze]
|
13
11
|
s.email = "flori@ping.de".freeze
|
12
|
+
|
14
13
|
s.extra_rdoc_files = ["README.md".freeze]
|
15
|
-
s.files = ["./tests/test_helper.rb".freeze, ".gitignore".freeze, ".travis.yml".freeze, "CHANGES.md".freeze, "Gemfile".freeze, "README-json-jruby.md".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "data/example.json".freeze, "data/index.html".freeze, "data/prototype.js".freeze, "diagrams/.keep".freeze, "ext/json/ext/fbuffer/fbuffer.h".freeze, "ext/json/ext/generator/depend".freeze, "ext/json/ext/generator/extconf.rb".freeze, "ext/json/ext/generator/generator.c".freeze, "ext/json/ext/generator/generator.h".freeze, "ext/json/ext/parser/depend".freeze, "ext/json/ext/parser/extconf.rb".freeze, "ext/json/ext/parser/parser.c".freeze, "ext/json/ext/parser/parser.h".freeze, "ext/json/ext/parser/parser.rl".freeze, "ext/json/extconf.rb".freeze, "install.rb".freeze, "java/src/json/ext/ByteListTranscoder.java".freeze, "java/src/json/ext/Generator.java".freeze, "java/src/json/ext/GeneratorMethods.java".freeze, "java/src/json/ext/GeneratorService.java".freeze, "java/src/json/ext/GeneratorState.java".freeze, "java/src/json/ext/OptionsReader.java".freeze, "java/src/json/ext/Parser.java".freeze, "java/src/json/ext/Parser.rl".freeze, "java/src/json/ext/ParserService.java".freeze, "java/src/json/ext/RuntimeInfo.java".freeze, "java/src/json/ext/StringDecoder.java".freeze, "java/src/json/ext/StringEncoder.java".freeze, "java/src/json/ext/Utils.java".freeze, "json-java.gemspec".freeze, "json.gemspec".freeze, "json_pure.gemspec".freeze, "lib/json.rb".freeze, "lib/json/add/bigdecimal.rb".freeze, "lib/json/add/complex.rb".freeze, "lib/json/add/core.rb".freeze, "lib/json/add/date.rb".freeze, "lib/json/add/date_time.rb".freeze, "lib/json/add/exception.rb".freeze, "lib/json/add/ostruct.rb".freeze, "lib/json/add/range.rb".freeze, "lib/json/add/rational.rb".freeze, "lib/json/add/regexp.rb".freeze, "lib/json/add/struct.rb".freeze, "lib/json/add/symbol.rb".freeze, "lib/json/add/time.rb".freeze, "lib/json/common.rb".freeze, "lib/json/ext.rb".freeze, "lib/json/ext/.keep".freeze, "lib/json/generic_object.rb".freeze, "lib/json/pure.rb".freeze, "lib/json/pure/generator.rb".freeze, "lib/json/pure/parser.rb".freeze, "lib/json/version.rb".freeze, "references/rfc7159.txt".freeze, "tests/fixtures/fail10.json".freeze, "tests/fixtures/fail11.json".freeze, "tests/fixtures/fail12.json".freeze, "tests/fixtures/fail13.json".freeze, "tests/fixtures/fail14.json".freeze, "tests/fixtures/fail18.json".freeze, "tests/fixtures/fail19.json".freeze, "tests/fixtures/fail2.json".freeze, "tests/fixtures/fail20.json".freeze, "tests/fixtures/fail21.json".freeze, "tests/fixtures/fail22.json".freeze, "tests/fixtures/fail23.json".freeze, "tests/fixtures/fail24.json".freeze, "tests/fixtures/fail25.json".freeze, "tests/fixtures/fail27.json".freeze, "tests/fixtures/fail28.json".freeze, "tests/fixtures/fail3.json".freeze, "tests/fixtures/fail4.json".freeze, "tests/fixtures/fail5.json".freeze, "tests/fixtures/fail6.json".freeze, "tests/fixtures/fail7.json".freeze, "tests/fixtures/fail8.json".freeze, "tests/fixtures/fail9.json".freeze, "tests/fixtures/obsolete_fail1.json".freeze, "tests/fixtures/pass1.json".freeze, "tests/fixtures/pass15.json".freeze, "tests/fixtures/pass16.json".freeze, "tests/fixtures/pass17.json".freeze, "tests/fixtures/pass2.json".freeze, "tests/fixtures/pass26.json".freeze, "tests/fixtures/pass3.json".freeze, "tests/json_addition_test.rb".freeze, "tests/json_common_interface_test.rb".freeze, "tests/json_encoding_test.rb".freeze, "tests/json_ext_parser_test.rb".freeze, "tests/json_fixtures_test.rb".freeze, "tests/json_generator_test.rb".freeze, "tests/json_generic_object_test.rb".freeze, "tests/json_parser_test.rb".freeze, "tests/json_string_matching_test.rb".freeze, "tests/test_helper.rb".freeze, "tools/diff.sh".freeze, "tools/fuzz.rb".freeze, "tools/server.rb".freeze]
|
16
|
-
s.homepage = "http://flori.github.com/json".freeze
|
17
|
-
s.licenses = ["Ruby".freeze]
|
18
14
|
s.rdoc_options = ["--title".freeze, "JSON implemention for ruby".freeze, "--main".freeze, "README.md".freeze]
|
19
|
-
s.
|
20
|
-
|
21
|
-
|
22
|
-
|
15
|
+
s.files = [
|
16
|
+
"CHANGES.md".freeze,
|
17
|
+
"Gemfile".freeze,
|
18
|
+
"LICENSE".freeze,
|
19
|
+
"README.md".freeze,
|
20
|
+
"VERSION".freeze,
|
21
|
+
"json_pure.gemspec".freeze,
|
22
|
+
"lib/json.rb".freeze,
|
23
|
+
"lib/json/add/bigdecimal.rb".freeze,
|
24
|
+
"lib/json/add/complex.rb".freeze,
|
25
|
+
"lib/json/add/core.rb".freeze,
|
26
|
+
"lib/json/add/date.rb".freeze,
|
27
|
+
"lib/json/add/date_time.rb".freeze,
|
28
|
+
"lib/json/add/exception.rb".freeze,
|
29
|
+
"lib/json/add/ostruct.rb".freeze,
|
30
|
+
"lib/json/add/range.rb".freeze,
|
31
|
+
"lib/json/add/rational.rb".freeze,
|
32
|
+
"lib/json/add/regexp.rb".freeze,
|
33
|
+
"lib/json/add/set.rb".freeze,
|
34
|
+
"lib/json/add/struct.rb".freeze,
|
35
|
+
"lib/json/add/symbol.rb".freeze,
|
36
|
+
"lib/json/add/time.rb".freeze,
|
37
|
+
"lib/json/common.rb".freeze,
|
38
|
+
"lib/json/ext.rb".freeze,
|
39
|
+
"lib/json/ext/.keep".freeze,
|
40
|
+
"lib/json/generic_object.rb".freeze,
|
41
|
+
"lib/json/pure.rb".freeze,
|
42
|
+
"lib/json/pure/generator.rb".freeze,
|
43
|
+
"lib/json/pure/parser.rb".freeze,
|
44
|
+
"lib/json/version.rb".freeze,
|
45
|
+
] + Dir["tests/**/*"]
|
46
|
+
s.homepage = "http://flori.github.com/json".freeze
|
47
|
+
s.metadata = {
|
48
|
+
'bug_tracker_uri' => 'https://github.com/flori/json/issues',
|
49
|
+
'changelog_uri' => 'https://github.com/flori/json/blob/master/CHANGES.md',
|
50
|
+
'documentation_uri' => 'http://flori.github.io/json/doc/index.html',
|
51
|
+
'homepage_uri' => 'http://flori.github.io/json/',
|
52
|
+
'source_code_uri' => 'https://github.com/flori/json',
|
53
|
+
'wiki_uri' => 'https://github.com/flori/json/wiki'
|
54
|
+
}
|
23
55
|
|
24
|
-
|
25
|
-
|
56
|
+
s.required_ruby_version = Gem::Requirement.new(">= 2.0".freeze)
|
57
|
+
s.test_files = ["./tests/test_helper.rb".freeze]
|
26
58
|
|
27
|
-
|
28
|
-
|
29
|
-
s.add_development_dependency(%q<test-unit>.freeze, ["~> 2.0"])
|
30
|
-
else
|
31
|
-
s.add_dependency(%q<rake>.freeze, [">= 0"])
|
32
|
-
s.add_dependency(%q<test-unit>.freeze, ["~> 2.0"])
|
33
|
-
end
|
34
|
-
else
|
35
|
-
s.add_dependency(%q<rake>.freeze, [">= 0"])
|
36
|
-
s.add_dependency(%q<test-unit>.freeze, ["~> 2.0"])
|
37
|
-
end
|
59
|
+
s.add_development_dependency "rake"
|
60
|
+
s.add_development_dependency "test-unit"
|
38
61
|
end
|
data/lib/json.rb
CHANGED
@@ -2,55 +2,575 @@
|
|
2
2
|
require 'json/common'
|
3
3
|
|
4
4
|
##
|
5
|
-
# = JavaScript Object Notation (JSON)
|
5
|
+
# = JavaScript \Object Notation (\JSON)
|
6
6
|
#
|
7
|
-
# JSON is a lightweight data-interchange format.
|
8
|
-
# humans to read and write. Plus, equally simple for machines to generate or parse.
|
9
|
-
# JSON is completely language agnostic, making it the ideal interchange format.
|
7
|
+
# \JSON is a lightweight data-interchange format.
|
10
8
|
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
9
|
+
# A \JSON value is one of the following:
|
10
|
+
# - Double-quoted text: <tt>"foo"</tt>.
|
11
|
+
# - Number: +1+, +1.0+, +2.0e2+.
|
12
|
+
# - Boolean: +true+, +false+.
|
13
|
+
# - Null: +null+.
|
14
|
+
# - \Array: an ordered list of values, enclosed by square brackets:
|
15
|
+
# ["foo", 1, 1.0, 2.0e2, true, false, null]
|
14
16
|
#
|
15
|
-
#
|
17
|
+
# - \Object: a collection of name/value pairs, enclosed by curly braces;
|
18
|
+
# each name is double-quoted text;
|
19
|
+
# the values may be any \JSON values:
|
20
|
+
# {"a": "foo", "b": 1, "c": 1.0, "d": 2.0e2, "e": true, "f": false, "g": null}
|
16
21
|
#
|
17
|
-
#
|
22
|
+
# A \JSON array or object may contain nested arrays, objects, and scalars
|
23
|
+
# to any depth:
|
24
|
+
# {"foo": {"bar": 1, "baz": 2}, "bat": [0, 1, 2]}
|
25
|
+
# [{"foo": 0, "bar": 1}, ["baz", 2]]
|
18
26
|
#
|
19
|
-
#
|
20
|
-
# your existing application:
|
27
|
+
# == Using \Module \JSON
|
21
28
|
#
|
29
|
+
# To make module \JSON available in your code, begin with:
|
22
30
|
# require 'json'
|
23
31
|
#
|
24
|
-
#
|
25
|
-
# puts my_hash["hello"] => "goodbye"
|
32
|
+
# All examples here assume that this has been done.
|
26
33
|
#
|
27
|
-
#
|
28
|
-
# the argument to be a string and can't convert objects like a hash or array.
|
34
|
+
# === Parsing \JSON
|
29
35
|
#
|
30
|
-
#
|
36
|
+
# You can parse a \String containing \JSON data using
|
37
|
+
# either of two methods:
|
38
|
+
# - <tt>JSON.parse(source, opts)</tt>
|
39
|
+
# - <tt>JSON.parse!(source, opts)</tt>
|
31
40
|
#
|
32
|
-
#
|
41
|
+
# where
|
42
|
+
# - +source+ is a Ruby object.
|
43
|
+
# - +opts+ is a \Hash object containing options
|
44
|
+
# that control both input allowed and output formatting.
|
33
45
|
#
|
34
|
-
#
|
35
|
-
#
|
46
|
+
# The difference between the two methods
|
47
|
+
# is that JSON.parse! omits some checks
|
48
|
+
# and may not be safe for some +source+ data;
|
49
|
+
# use it only for data from trusted sources.
|
50
|
+
# Use the safer method JSON.parse for less trusted sources.
|
36
51
|
#
|
37
|
-
#
|
52
|
+
# ==== Parsing \JSON Arrays
|
38
53
|
#
|
39
|
-
#
|
40
|
-
#
|
54
|
+
# When +source+ is a \JSON array, JSON.parse by default returns a Ruby \Array:
|
55
|
+
# json = '["foo", 1, 1.0, 2.0e2, true, false, null]'
|
56
|
+
# ruby = JSON.parse(json)
|
57
|
+
# ruby # => ["foo", 1, 1.0, 200.0, true, false, nil]
|
58
|
+
# ruby.class # => Array
|
41
59
|
#
|
42
|
-
#
|
60
|
+
# The \JSON array may contain nested arrays, objects, and scalars
|
61
|
+
# to any depth:
|
62
|
+
# json = '[{"foo": 0, "bar": 1}, ["baz", 2]]'
|
63
|
+
# JSON.parse(json) # => [{"foo"=>0, "bar"=>1}, ["baz", 2]]
|
43
64
|
#
|
44
|
-
#
|
45
|
-
#
|
65
|
+
# ==== Parsing \JSON \Objects
|
66
|
+
#
|
67
|
+
# When the source is a \JSON object, JSON.parse by default returns a Ruby \Hash:
|
68
|
+
# json = '{"a": "foo", "b": 1, "c": 1.0, "d": 2.0e2, "e": true, "f": false, "g": null}'
|
69
|
+
# ruby = JSON.parse(json)
|
70
|
+
# ruby # => {"a"=>"foo", "b"=>1, "c"=>1.0, "d"=>200.0, "e"=>true, "f"=>false, "g"=>nil}
|
71
|
+
# ruby.class # => Hash
|
72
|
+
#
|
73
|
+
# The \JSON object may contain nested arrays, objects, and scalars
|
74
|
+
# to any depth:
|
75
|
+
# json = '{"foo": {"bar": 1, "baz": 2}, "bat": [0, 1, 2]}'
|
76
|
+
# JSON.parse(json) # => {"foo"=>{"bar"=>1, "baz"=>2}, "bat"=>[0, 1, 2]}
|
77
|
+
#
|
78
|
+
# ==== Parsing \JSON Scalars
|
79
|
+
#
|
80
|
+
# When the source is a \JSON scalar (not an array or object),
|
81
|
+
# JSON.parse returns a Ruby scalar.
|
82
|
+
#
|
83
|
+
# \String:
|
84
|
+
# ruby = JSON.parse('"foo"')
|
85
|
+
# ruby # => 'foo'
|
86
|
+
# ruby.class # => String
|
87
|
+
# \Integer:
|
88
|
+
# ruby = JSON.parse('1')
|
89
|
+
# ruby # => 1
|
90
|
+
# ruby.class # => Integer
|
91
|
+
# \Float:
|
92
|
+
# ruby = JSON.parse('1.0')
|
93
|
+
# ruby # => 1.0
|
94
|
+
# ruby.class # => Float
|
95
|
+
# ruby = JSON.parse('2.0e2')
|
96
|
+
# ruby # => 200
|
97
|
+
# ruby.class # => Float
|
98
|
+
# Boolean:
|
99
|
+
# ruby = JSON.parse('true')
|
100
|
+
# ruby # => true
|
101
|
+
# ruby.class # => TrueClass
|
102
|
+
# ruby = JSON.parse('false')
|
103
|
+
# ruby # => false
|
104
|
+
# ruby.class # => FalseClass
|
105
|
+
# Null:
|
106
|
+
# ruby = JSON.parse('null')
|
107
|
+
# ruby # => nil
|
108
|
+
# ruby.class # => NilClass
|
109
|
+
#
|
110
|
+
# ==== Parsing Options
|
111
|
+
#
|
112
|
+
# ====== Input Options
|
113
|
+
#
|
114
|
+
# Option +max_nesting+ (\Integer) specifies the maximum nesting depth allowed;
|
115
|
+
# defaults to +100+; specify +false+ to disable depth checking.
|
116
|
+
#
|
117
|
+
# With the default, +false+:
|
118
|
+
# source = '[0, [1, [2, [3]]]]'
|
119
|
+
# ruby = JSON.parse(source)
|
120
|
+
# ruby # => [0, [1, [2, [3]]]]
|
121
|
+
# Too deep:
|
122
|
+
# # Raises JSON::NestingError (nesting of 2 is too deep):
|
123
|
+
# JSON.parse(source, {max_nesting: 1})
|
124
|
+
# Bad value:
|
125
|
+
# # Raises TypeError (wrong argument type Symbol (expected Fixnum)):
|
126
|
+
# JSON.parse(source, {max_nesting: :foo})
|
127
|
+
#
|
128
|
+
# ---
|
129
|
+
#
|
130
|
+
# Option +allow_nan+ (boolean) specifies whether to allow
|
131
|
+
# NaN, Infinity, and MinusInfinity in +source+;
|
132
|
+
# defaults to +false+.
|
133
|
+
#
|
134
|
+
# With the default, +false+:
|
135
|
+
# # Raises JSON::ParserError (225: unexpected token at '[NaN]'):
|
136
|
+
# JSON.parse('[NaN]')
|
137
|
+
# # Raises JSON::ParserError (232: unexpected token at '[Infinity]'):
|
138
|
+
# JSON.parse('[Infinity]')
|
139
|
+
# # Raises JSON::ParserError (248: unexpected token at '[-Infinity]'):
|
140
|
+
# JSON.parse('[-Infinity]')
|
141
|
+
# Allow:
|
142
|
+
# source = '[NaN, Infinity, -Infinity]'
|
143
|
+
# ruby = JSON.parse(source, {allow_nan: true})
|
144
|
+
# ruby # => [NaN, Infinity, -Infinity]
|
145
|
+
#
|
146
|
+
# ====== Output Options
|
147
|
+
#
|
148
|
+
# Option +symbolize_names+ (boolean) specifies whether returned \Hash keys
|
149
|
+
# should be Symbols;
|
150
|
+
# defaults to +false+ (use Strings).
|
151
|
+
#
|
152
|
+
# With the default, +false+:
|
153
|
+
# source = '{"a": "foo", "b": 1.0, "c": true, "d": false, "e": null}'
|
154
|
+
# ruby = JSON.parse(source)
|
155
|
+
# ruby # => {"a"=>"foo", "b"=>1.0, "c"=>true, "d"=>false, "e"=>nil}
|
156
|
+
# Use Symbols:
|
157
|
+
# ruby = JSON.parse(source, {symbolize_names: true})
|
158
|
+
# ruby # => {:a=>"foo", :b=>1.0, :c=>true, :d=>false, :e=>nil}
|
159
|
+
#
|
160
|
+
# ---
|
161
|
+
#
|
162
|
+
# Option +object_class+ (\Class) specifies the Ruby class to be used
|
163
|
+
# for each \JSON object;
|
164
|
+
# defaults to \Hash.
|
165
|
+
#
|
166
|
+
# With the default, \Hash:
|
167
|
+
# source = '{"a": "foo", "b": 1.0, "c": true, "d": false, "e": null}'
|
168
|
+
# ruby = JSON.parse(source)
|
169
|
+
# ruby.class # => Hash
|
170
|
+
# Use class \OpenStruct:
|
171
|
+
# ruby = JSON.parse(source, {object_class: OpenStruct})
|
172
|
+
# ruby # => #<OpenStruct a="foo", b=1.0, c=true, d=false, e=nil>
|
173
|
+
#
|
174
|
+
# ---
|
175
|
+
#
|
176
|
+
# Option +array_class+ (\Class) specifies the Ruby class to be used
|
177
|
+
# for each \JSON array;
|
178
|
+
# defaults to \Array.
|
179
|
+
#
|
180
|
+
# With the default, \Array:
|
181
|
+
# source = '["foo", 1.0, true, false, null]'
|
182
|
+
# ruby = JSON.parse(source)
|
183
|
+
# ruby.class # => Array
|
184
|
+
# Use class \Set:
|
185
|
+
# ruby = JSON.parse(source, {array_class: Set})
|
186
|
+
# ruby # => #<Set: {"foo", 1.0, true, false, nil}>
|
187
|
+
#
|
188
|
+
# ---
|
189
|
+
#
|
190
|
+
# Option +create_additions+ (boolean) specifies whether to use \JSON additions in parsing.
|
191
|
+
# See {\JSON Additions}[#module-JSON-label-JSON+Additions].
|
192
|
+
#
|
193
|
+
# === Generating \JSON
|
194
|
+
#
|
195
|
+
# To generate a Ruby \String containing \JSON data,
|
196
|
+
# use method <tt>JSON.generate(source, opts)</tt>, where
|
197
|
+
# - +source+ is a Ruby object.
|
198
|
+
# - +opts+ is a \Hash object containing options
|
199
|
+
# that control both input allowed and output formatting.
|
200
|
+
#
|
201
|
+
# ==== Generating \JSON from Arrays
|
202
|
+
#
|
203
|
+
# When the source is a Ruby \Array, JSON.generate returns
|
204
|
+
# a \String containing a \JSON array:
|
205
|
+
# ruby = [0, 's', :foo]
|
206
|
+
# json = JSON.generate(ruby)
|
207
|
+
# json # => '[0,"s","foo"]'
|
208
|
+
#
|
209
|
+
# The Ruby \Array array may contain nested arrays, hashes, and scalars
|
210
|
+
# to any depth:
|
211
|
+
# ruby = [0, [1, 2], {foo: 3, bar: 4}]
|
212
|
+
# json = JSON.generate(ruby)
|
213
|
+
# json # => '[0,[1,2],{"foo":3,"bar":4}]'
|
214
|
+
#
|
215
|
+
# ==== Generating \JSON from Hashes
|
216
|
+
#
|
217
|
+
# When the source is a Ruby \Hash, JSON.generate returns
|
218
|
+
# a \String containing a \JSON object:
|
219
|
+
# ruby = {foo: 0, bar: 's', baz: :bat}
|
220
|
+
# json = JSON.generate(ruby)
|
221
|
+
# json # => '{"foo":0,"bar":"s","baz":"bat"}'
|
222
|
+
#
|
223
|
+
# The Ruby \Hash array may contain nested arrays, hashes, and scalars
|
224
|
+
# to any depth:
|
225
|
+
# ruby = {foo: [0, 1], bar: {baz: 2, bat: 3}, bam: :bad}
|
226
|
+
# json = JSON.generate(ruby)
|
227
|
+
# json # => '{"foo":[0,1],"bar":{"baz":2,"bat":3},"bam":"bad"}'
|
228
|
+
#
|
229
|
+
# ==== Generating \JSON from Other Objects
|
230
|
+
#
|
231
|
+
# When the source is neither an \Array nor a \Hash,
|
232
|
+
# the generated \JSON data depends on the class of the source.
|
233
|
+
#
|
234
|
+
# When the source is a Ruby \Integer or \Float, JSON.generate returns
|
235
|
+
# a \String containing a \JSON number:
|
236
|
+
# JSON.generate(42) # => '42'
|
237
|
+
# JSON.generate(0.42) # => '0.42'
|
238
|
+
#
|
239
|
+
# When the source is a Ruby \String, JSON.generate returns
|
240
|
+
# a \String containing a \JSON string (with double-quotes):
|
241
|
+
# JSON.generate('A string') # => '"A string"'
|
242
|
+
#
|
243
|
+
# When the source is +true+, +false+ or +nil+, JSON.generate returns
|
244
|
+
# a \String containing the corresponding \JSON token:
|
245
|
+
# JSON.generate(true) # => 'true'
|
246
|
+
# JSON.generate(false) # => 'false'
|
247
|
+
# JSON.generate(nil) # => 'null'
|
248
|
+
#
|
249
|
+
# When the source is none of the above, JSON.generate returns
|
250
|
+
# a \String containing a \JSON string representation of the source:
|
251
|
+
# JSON.generate(:foo) # => '"foo"'
|
252
|
+
# JSON.generate(Complex(0, 0)) # => '"0+0i"'
|
253
|
+
# JSON.generate(Dir.new('.')) # => '"#<Dir>"'
|
254
|
+
#
|
255
|
+
# ==== Generating Options
|
256
|
+
#
|
257
|
+
# ====== Input Options
|
46
258
|
#
|
47
|
-
#
|
48
|
-
#
|
49
|
-
#
|
259
|
+
# Option +allow_nan+ (boolean) specifies whether
|
260
|
+
# +NaN+, +Infinity+, and <tt>-Infinity</tt> may be generated;
|
261
|
+
# defaults to +false+.
|
50
262
|
#
|
263
|
+
# With the default, +false+:
|
264
|
+
# # Raises JSON::GeneratorError (920: NaN not allowed in JSON):
|
265
|
+
# JSON.generate(JSON::NaN)
|
266
|
+
# # Raises JSON::GeneratorError (917: Infinity not allowed in JSON):
|
267
|
+
# JSON.generate(JSON::Infinity)
|
268
|
+
# # Raises JSON::GeneratorError (917: -Infinity not allowed in JSON):
|
269
|
+
# JSON.generate(JSON::MinusInfinity)
|
270
|
+
#
|
271
|
+
# Allow:
|
272
|
+
# ruby = [Float::NaN, Float::Infinity, Float::MinusInfinity]
|
273
|
+
# JSON.generate(ruby, allow_nan: true) # => '[NaN,Infinity,-Infinity]'
|
274
|
+
#
|
275
|
+
# ---
|
276
|
+
#
|
277
|
+
# Option +max_nesting+ (\Integer) specifies the maximum nesting depth
|
278
|
+
# in +obj+; defaults to +100+.
|
279
|
+
#
|
280
|
+
# With the default, +100+:
|
281
|
+
# obj = [[[[[[0]]]]]]
|
282
|
+
# JSON.generate(obj) # => '[[[[[[0]]]]]]'
|
283
|
+
#
|
284
|
+
# Too deep:
|
285
|
+
# # Raises JSON::NestingError (nesting of 2 is too deep):
|
286
|
+
# JSON.generate(obj, max_nesting: 2)
|
287
|
+
#
|
288
|
+
# ====== Output Options
|
289
|
+
#
|
290
|
+
# The default formatting options generate the most compact
|
291
|
+
# \JSON data, all on one line and with no whitespace.
|
292
|
+
#
|
293
|
+
# You can use these formatting options to generate
|
294
|
+
# \JSON data in a more open format, using whitespace.
|
295
|
+
# See also JSON.pretty_generate.
|
296
|
+
#
|
297
|
+
# - Option +array_nl+ (\String) specifies a string (usually a newline)
|
298
|
+
# to be inserted after each \JSON array; defaults to the empty \String, <tt>''</tt>.
|
299
|
+
# - Option +object_nl+ (\String) specifies a string (usually a newline)
|
300
|
+
# to be inserted after each \JSON object; defaults to the empty \String, <tt>''</tt>.
|
301
|
+
# - Option +indent+ (\String) specifies the string (usually spaces) to be
|
302
|
+
# used for indentation; defaults to the empty \String, <tt>''</tt>;
|
303
|
+
# defaults to the empty \String, <tt>''</tt>;
|
304
|
+
# has no effect unless options +array_nl+ or +object_nl+ specify newlines.
|
305
|
+
# - Option +space+ (\String) specifies a string (usually a space) to be
|
306
|
+
# inserted after the colon in each \JSON object's pair;
|
307
|
+
# defaults to the empty \String, <tt>''</tt>.
|
308
|
+
# - Option +space_before+ (\String) specifies a string (usually a space) to be
|
309
|
+
# inserted before the colon in each \JSON object's pair;
|
310
|
+
# defaults to the empty \String, <tt>''</tt>.
|
311
|
+
#
|
312
|
+
# In this example, +obj+ is used first to generate the shortest
|
313
|
+
# \JSON data (no whitespace), then again with all formatting options
|
314
|
+
# specified:
|
315
|
+
#
|
316
|
+
# obj = {foo: [:bar, :baz], bat: {bam: 0, bad: 1}}
|
317
|
+
# json = JSON.generate(obj)
|
318
|
+
# puts 'Compact:', json
|
319
|
+
# opts = {
|
320
|
+
# array_nl: "\n",
|
321
|
+
# object_nl: "\n",
|
322
|
+
# indent: ' ',
|
323
|
+
# space_before: ' ',
|
324
|
+
# space: ' '
|
325
|
+
# }
|
326
|
+
# puts 'Open:', JSON.generate(obj, opts)
|
327
|
+
#
|
328
|
+
# Output:
|
329
|
+
# Compact:
|
330
|
+
# {"foo":["bar","baz"],"bat":{"bam":0,"bad":1}}
|
331
|
+
# Open:
|
332
|
+
# {
|
333
|
+
# "foo" : [
|
334
|
+
# "bar",
|
335
|
+
# "baz"
|
336
|
+
# ],
|
337
|
+
# "bat" : {
|
338
|
+
# "bam" : 0,
|
339
|
+
# "bad" : 1
|
340
|
+
# }
|
341
|
+
# }
|
342
|
+
#
|
343
|
+
# == \JSON Additions
|
344
|
+
#
|
345
|
+
# When you "round trip" a non-\String object from Ruby to \JSON and back,
|
346
|
+
# you have a new \String, instead of the object you began with:
|
347
|
+
# ruby0 = Range.new(0, 2)
|
348
|
+
# json = JSON.generate(ruby0)
|
349
|
+
# json # => '0..2"'
|
350
|
+
# ruby1 = JSON.parse(json)
|
351
|
+
# ruby1 # => '0..2'
|
352
|
+
# ruby1.class # => String
|
353
|
+
#
|
354
|
+
# You can use \JSON _additions_ to preserve the original object.
|
355
|
+
# The addition is an extension of a ruby class, so that:
|
356
|
+
# - \JSON.generate stores more information in the \JSON string.
|
357
|
+
# - \JSON.parse, called with option +create_additions+,
|
358
|
+
# uses that information to create a proper Ruby object.
|
359
|
+
#
|
360
|
+
# This example shows a \Range being generated into \JSON
|
361
|
+
# and parsed back into Ruby, both without and with
|
362
|
+
# the addition for \Range:
|
363
|
+
# ruby = Range.new(0, 2)
|
364
|
+
# # This passage does not use the addition for Range.
|
365
|
+
# json0 = JSON.generate(ruby)
|
366
|
+
# ruby0 = JSON.parse(json0)
|
367
|
+
# # This passage uses the addition for Range.
|
368
|
+
# require 'json/add/range'
|
369
|
+
# json1 = JSON.generate(ruby)
|
370
|
+
# ruby1 = JSON.parse(json1, create_additions: true)
|
371
|
+
# # Make a nice display.
|
372
|
+
# display = <<EOT
|
373
|
+
# Generated JSON:
|
374
|
+
# Without addition: #{json0} (#{json0.class})
|
375
|
+
# With addition: #{json1} (#{json1.class})
|
376
|
+
# Parsed JSON:
|
377
|
+
# Without addition: #{ruby0.inspect} (#{ruby0.class})
|
378
|
+
# With addition: #{ruby1.inspect} (#{ruby1.class})
|
379
|
+
# EOT
|
380
|
+
# puts display
|
381
|
+
#
|
382
|
+
# This output shows the different results:
|
383
|
+
# Generated JSON:
|
384
|
+
# Without addition: "0..2" (String)
|
385
|
+
# With addition: {"json_class":"Range","a":[0,2,false]} (String)
|
386
|
+
# Parsed JSON:
|
387
|
+
# Without addition: "0..2" (String)
|
388
|
+
# With addition: 0..2 (Range)
|
389
|
+
#
|
390
|
+
# The \JSON module includes additions for certain classes.
|
391
|
+
# You can also craft custom additions.
|
392
|
+
# See {Custom \JSON Additions}[#module-JSON-label-Custom+JSON+Additions].
|
393
|
+
#
|
394
|
+
# === Built-in Additions
|
395
|
+
#
|
396
|
+
# The \JSON module includes additions for certain classes.
|
397
|
+
# To use an addition, +require+ its source:
|
398
|
+
# - BigDecimal: <tt>require 'json/add/bigdecimal'</tt>
|
399
|
+
# - Complex: <tt>require 'json/add/complex'</tt>
|
400
|
+
# - Date: <tt>require 'json/add/date'</tt>
|
401
|
+
# - DateTime: <tt>require 'json/add/date_time'</tt>
|
402
|
+
# - Exception: <tt>require 'json/add/exception'</tt>
|
403
|
+
# - OpenStruct: <tt>require 'json/add/ostruct'</tt>
|
404
|
+
# - Range: <tt>require 'json/add/range'</tt>
|
405
|
+
# - Rational: <tt>require 'json/add/rational'</tt>
|
406
|
+
# - Regexp: <tt>require 'json/add/regexp'</tt>
|
407
|
+
# - Set: <tt>require 'json/add/set'</tt>
|
408
|
+
# - Struct: <tt>require 'json/add/struct'</tt>
|
409
|
+
# - Symbol: <tt>require 'json/add/symbol'</tt>
|
410
|
+
# - Time: <tt>require 'json/add/time'</tt>
|
411
|
+
#
|
412
|
+
# To reduce punctuation clutter, the examples below
|
413
|
+
# show the generated \JSON via +puts+, rather than the usual +inspect+,
|
414
|
+
#
|
415
|
+
# \BigDecimal:
|
416
|
+
# require 'json/add/bigdecimal'
|
417
|
+
# ruby0 = BigDecimal(0) # 0.0
|
418
|
+
# json = JSON.generate(ruby0) # {"json_class":"BigDecimal","b":"27:0.0"}
|
419
|
+
# ruby1 = JSON.parse(json, create_additions: true) # 0.0
|
420
|
+
# ruby1.class # => BigDecimal
|
421
|
+
#
|
422
|
+
# \Complex:
|
423
|
+
# require 'json/add/complex'
|
424
|
+
# ruby0 = Complex(1+0i) # 1+0i
|
425
|
+
# json = JSON.generate(ruby0) # {"json_class":"Complex","r":1,"i":0}
|
426
|
+
# ruby1 = JSON.parse(json, create_additions: true) # 1+0i
|
427
|
+
# ruby1.class # Complex
|
428
|
+
#
|
429
|
+
# \Date:
|
430
|
+
# require 'json/add/date'
|
431
|
+
# ruby0 = Date.today # 2020-05-02
|
432
|
+
# json = JSON.generate(ruby0) # {"json_class":"Date","y":2020,"m":5,"d":2,"sg":2299161.0}
|
433
|
+
# ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02
|
434
|
+
# ruby1.class # Date
|
435
|
+
#
|
436
|
+
# \DateTime:
|
437
|
+
# require 'json/add/date_time'
|
438
|
+
# ruby0 = DateTime.now # 2020-05-02T10:38:13-05:00
|
439
|
+
# 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}
|
440
|
+
# ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02T10:38:13-05:00
|
441
|
+
# ruby1.class # DateTime
|
442
|
+
#
|
443
|
+
# \Exception (and its subclasses including \RuntimeError):
|
444
|
+
# require 'json/add/exception'
|
445
|
+
# ruby0 = Exception.new('A message') # A message
|
446
|
+
# json = JSON.generate(ruby0) # {"json_class":"Exception","m":"A message","b":null}
|
447
|
+
# ruby1 = JSON.parse(json, create_additions: true) # A message
|
448
|
+
# ruby1.class # Exception
|
449
|
+
# ruby0 = RuntimeError.new('Another message') # Another message
|
450
|
+
# json = JSON.generate(ruby0) # {"json_class":"RuntimeError","m":"Another message","b":null}
|
451
|
+
# ruby1 = JSON.parse(json, create_additions: true) # Another message
|
452
|
+
# ruby1.class # RuntimeError
|
453
|
+
#
|
454
|
+
# \OpenStruct:
|
455
|
+
# require 'json/add/ostruct'
|
456
|
+
# ruby0 = OpenStruct.new(name: 'Matz', language: 'Ruby') # #<OpenStruct name="Matz", language="Ruby">
|
457
|
+
# json = JSON.generate(ruby0) # {"json_class":"OpenStruct","t":{"name":"Matz","language":"Ruby"}}
|
458
|
+
# ruby1 = JSON.parse(json, create_additions: true) # #<OpenStruct name="Matz", language="Ruby">
|
459
|
+
# ruby1.class # OpenStruct
|
460
|
+
#
|
461
|
+
# \Range:
|
462
|
+
# require 'json/add/range'
|
463
|
+
# ruby0 = Range.new(0, 2) # 0..2
|
464
|
+
# json = JSON.generate(ruby0) # {"json_class":"Range","a":[0,2,false]}
|
465
|
+
# ruby1 = JSON.parse(json, create_additions: true) # 0..2
|
466
|
+
# ruby1.class # Range
|
467
|
+
#
|
468
|
+
# \Rational:
|
469
|
+
# require 'json/add/rational'
|
470
|
+
# ruby0 = Rational(1, 3) # 1/3
|
471
|
+
# json = JSON.generate(ruby0) # {"json_class":"Rational","n":1,"d":3}
|
472
|
+
# ruby1 = JSON.parse(json, create_additions: true) # 1/3
|
473
|
+
# ruby1.class # Rational
|
474
|
+
#
|
475
|
+
# \Regexp:
|
476
|
+
# require 'json/add/regexp'
|
477
|
+
# ruby0 = Regexp.new('foo') # (?-mix:foo)
|
478
|
+
# json = JSON.generate(ruby0) # {"json_class":"Regexp","o":0,"s":"foo"}
|
479
|
+
# ruby1 = JSON.parse(json, create_additions: true) # (?-mix:foo)
|
480
|
+
# ruby1.class # Regexp
|
481
|
+
#
|
482
|
+
# \Set:
|
483
|
+
# require 'json/add/set'
|
484
|
+
# ruby0 = Set.new([0, 1, 2]) # #<Set: {0, 1, 2}>
|
485
|
+
# json = JSON.generate(ruby0) # {"json_class":"Set","a":[0,1,2]}
|
486
|
+
# ruby1 = JSON.parse(json, create_additions: true) # #<Set: {0, 1, 2}>
|
487
|
+
# ruby1.class # Set
|
488
|
+
#
|
489
|
+
# \Struct:
|
490
|
+
# require 'json/add/struct'
|
491
|
+
# Customer = Struct.new(:name, :address) # Customer
|
492
|
+
# ruby0 = Customer.new("Dave", "123 Main") # #<struct Customer name="Dave", address="123 Main">
|
493
|
+
# json = JSON.generate(ruby0) # {"json_class":"Customer","v":["Dave","123 Main"]}
|
494
|
+
# ruby1 = JSON.parse(json, create_additions: true) # #<struct Customer name="Dave", address="123 Main">
|
495
|
+
# ruby1.class # Customer
|
496
|
+
#
|
497
|
+
# \Symbol:
|
498
|
+
# require 'json/add/symbol'
|
499
|
+
# ruby0 = :foo # foo
|
500
|
+
# json = JSON.generate(ruby0) # {"json_class":"Symbol","s":"foo"}
|
501
|
+
# ruby1 = JSON.parse(json, create_additions: true) # foo
|
502
|
+
# ruby1.class # Symbol
|
503
|
+
#
|
504
|
+
# \Time:
|
505
|
+
# require 'json/add/time'
|
506
|
+
# ruby0 = Time.now # 2020-05-02 11:28:26 -0500
|
507
|
+
# json = JSON.generate(ruby0) # {"json_class":"Time","s":1588436906,"n":840560000}
|
508
|
+
# ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02 11:28:26 -0500
|
509
|
+
# ruby1.class # Time
|
510
|
+
#
|
511
|
+
#
|
512
|
+
# === Custom \JSON Additions
|
513
|
+
#
|
514
|
+
# In addition to the \JSON additions provided,
|
515
|
+
# you can craft \JSON additions of your own,
|
516
|
+
# either for Ruby built-in classes or for user-defined classes.
|
517
|
+
#
|
518
|
+
# Here's a user-defined class +Foo+:
|
519
|
+
# class Foo
|
520
|
+
# attr_accessor :bar, :baz
|
521
|
+
# def initialize(bar, baz)
|
522
|
+
# self.bar = bar
|
523
|
+
# self.baz = baz
|
524
|
+
# end
|
525
|
+
# end
|
526
|
+
#
|
527
|
+
# Here's the \JSON addition for it:
|
528
|
+
# # Extend class Foo with JSON addition.
|
529
|
+
# class Foo
|
530
|
+
# # Serialize Foo object with its class name and arguments
|
531
|
+
# def to_json(*args)
|
532
|
+
# {
|
533
|
+
# JSON.create_id => self.class.name,
|
534
|
+
# 'a' => [ bar, baz ]
|
535
|
+
# }.to_json(*args)
|
536
|
+
# end
|
537
|
+
# # Deserialize JSON string by constructing new Foo object with arguments.
|
538
|
+
# def self.json_create(object)
|
539
|
+
# new(*object['a'])
|
540
|
+
# end
|
541
|
+
# end
|
542
|
+
#
|
543
|
+
# Demonstration:
|
51
544
|
# require 'json'
|
545
|
+
# # This Foo object has no custom addition.
|
546
|
+
# foo0 = Foo.new(0, 1)
|
547
|
+
# json0 = JSON.generate(foo0)
|
548
|
+
# obj0 = JSON.parse(json0)
|
549
|
+
# # Lood the custom addition.
|
550
|
+
# require_relative 'foo_addition'
|
551
|
+
# # This foo has the custom addition.
|
552
|
+
# foo1 = Foo.new(0, 1)
|
553
|
+
# json1 = JSON.generate(foo1)
|
554
|
+
# obj1 = JSON.parse(json1, create_additions: true)
|
555
|
+
# # Make a nice display.
|
556
|
+
# display = <<EOT
|
557
|
+
# Generated JSON:
|
558
|
+
# Without custom addition: #{json0} (#{json0.class})
|
559
|
+
# With custom addition: #{json1} (#{json1.class})
|
560
|
+
# Parsed JSON:
|
561
|
+
# Without custom addition: #{obj0.inspect} (#{obj0.class})
|
562
|
+
# With custom addition: #{obj1.inspect} (#{obj1.class})
|
563
|
+
# EOT
|
564
|
+
# puts display
|
565
|
+
#
|
566
|
+
# Output:
|
52
567
|
#
|
53
|
-
#
|
568
|
+
# Generated JSON:
|
569
|
+
# Without custom addition: "#<Foo:0x0000000006534e80>" (String)
|
570
|
+
# With custom addition: {"json_class":"Foo","a":[0,1]} (String)
|
571
|
+
# Parsed JSON:
|
572
|
+
# Without custom addition: "#<Foo:0x0000000006534e80>" (String)
|
573
|
+
# With custom addition: #<Foo:0x0000000006473bb8 @bar=0, @baz=1> (Foo)
|
54
574
|
#
|
55
575
|
module JSON
|
56
576
|
require 'json/version'
|