multi_json 1.21.0-java → 1.21.2-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +6 -6
- data/lib/multi_json/adapter_selector.rb +7 -7
- data/lib/multi_json/adapters/json_gem.rb +36 -4
- data/lib/multi_json/adapters/oj_common.rb +7 -1
- data/lib/multi_json/legacy_constant.rb +56 -0
- data/lib/multi_json/options_cache.rb +7 -11
- data/lib/multi_json/parse_error.rb +9 -4
- data/lib/multi_json/version.rb +1 -1
- data/lib/multi_json.rb +1 -69
- metadata +6 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f39513c79d29c5f685d446260dbb6fd4c64c98b5b0c6ca0e2878cb17459c2b96
|
|
4
|
+
data.tar.gz: b409781aca3db81b53286c8c03f5ba2fd863a369ba2486d8ad5218444a2065db
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 30b775f43dcf242b98f5f950a8263dc59a3b8aee170cce3c42adcd511c310d82d3916d6a7d7b76e01085006082bf4707e59f9df0eb292e6224b17b942088ca2b
|
|
7
|
+
data.tar.gz: 6d0fb93ea606bb0275bf9627364c81b47ad9f48494cbd00fbfa7994c4802b31390bab0510451e5d882c13d2eaa566f4f63af12a325c5b2602282e3f2fdb5f444
|
data/README.md
CHANGED
|
@@ -179,15 +179,15 @@ MultiJSON tries to have intelligent defaulting. If any supported library is
|
|
|
179
179
|
already loaded, MultiJSON uses it before attempting to load others. When no
|
|
180
180
|
backend is preloaded, MultiJSON walks its preference list and uses the first
|
|
181
181
|
one that loads successfully. The list is split per platform — JRuby's
|
|
182
|
-
available adapter set differs from MRI's
|
|
183
|
-
ranks `json_gem` ahead of `fast_jsonparser`/`oj`/`yajl`
|
|
184
|
-
|
|
185
|
-
table below.
|
|
182
|
+
available adapter set differs from MRI's — but the bundled benchmark suite
|
|
183
|
+
ranks `json_gem` first on every engine: ahead of `fast_jsonparser`/`oj`/`yajl`
|
|
184
|
+
on Ruby 3.4+, and ahead of `jrjackson`/`gson` on JRuby 10. CI re-runs the
|
|
185
|
+
benchmark and fails if the observed ranking diverges from the table below.
|
|
186
186
|
|
|
187
187
|
| rank | MRI / TruffleRuby | JRuby |
|
|
188
188
|
| ---- | ----------------- | --------------- |
|
|
189
|
-
| 1 | The JSON gem |
|
|
190
|
-
| 2 | `fast_jsonparser` |
|
|
189
|
+
| 1 | The JSON gem | The JSON gem |
|
|
190
|
+
| 2 | `fast_jsonparser` | `jrjackson` |
|
|
191
191
|
| 3 | `oj` | `gson` |
|
|
192
192
|
| 4 | `yajl-ruby` | — |
|
|
193
193
|
|
|
@@ -20,15 +20,15 @@ module MultiJSON
|
|
|
20
20
|
#
|
|
21
21
|
# The hash order is split per platform: on MRI/TruffleRuby the
|
|
22
22
|
# bundled benchmark suite ranks json_gem ahead of fast_jsonparser/
|
|
23
|
-
# oj/yajl on Ruby 3.4+; on JRuby the
|
|
24
|
-
#
|
|
25
|
-
# CI re-runs the benchmark with
|
|
26
|
-
# if the observed ranking diverges.
|
|
27
|
-
# :
|
|
23
|
+
# oj/yajl on Ruby 3.4+; on JRuby 10 the json gem's Java extension
|
|
24
|
+
# outperforms JrJackson across the benchmark matrix, so json_gem
|
|
25
|
+
# leads there too. CI re-runs the benchmark with
|
|
26
|
+
# ``--verify-preference`` to fail if the observed ranking diverges.
|
|
27
|
+
# simplecov:disable
|
|
28
28
|
ADAPTERS = if RUBY_ENGINE == "jruby"
|
|
29
29
|
{
|
|
30
|
-
jr_jackson: {require: "jrjackson", loaded: "JrJackson"},
|
|
31
30
|
json_gem: {require: "json", loaded: "JSON::Ext::Parser"},
|
|
31
|
+
jr_jackson: {require: "jrjackson", loaded: "JrJackson"},
|
|
32
32
|
gson: {require: "gson", loaded: "Gson"},
|
|
33
33
|
fast_jsonparser: {require: "fast_jsonparser", loaded: "FastJsonparser"},
|
|
34
34
|
oj: {require: "oj", loaded: "Oj"},
|
|
@@ -44,7 +44,7 @@ module MultiJSON
|
|
|
44
44
|
gson: {require: "gson", loaded: "Gson"}
|
|
45
45
|
}.freeze
|
|
46
46
|
end
|
|
47
|
-
# :
|
|
47
|
+
# simplecov:enable
|
|
48
48
|
private_constant :ADAPTERS
|
|
49
49
|
|
|
50
50
|
# Backwards-compatible view of {ADAPTERS} that exposes only the
|
|
@@ -10,7 +10,7 @@ module MultiJSON
|
|
|
10
10
|
# Exception raised when JSON parsing fails
|
|
11
11
|
ParseError = ::JSON::ParserError
|
|
12
12
|
|
|
13
|
-
defaults :load, create_additions: false, quirks_mode: true
|
|
13
|
+
defaults :load, create_additions: false, quirks_mode: true if JSON::VERSION.to_i < 3 # simplecov:disable
|
|
14
14
|
|
|
15
15
|
PRETTY_STATE_PROTOTYPE = {
|
|
16
16
|
indent: " ",
|
|
@@ -44,7 +44,7 @@ module MultiJSON
|
|
|
44
44
|
raise ::JSON::ParserError, "Invalid UTF-8 byte sequence in JSON input" unless string.valid_encoding?
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
::JSON.parse(string, options)
|
|
47
|
+
::JSON.parse(string, **options)
|
|
48
48
|
end
|
|
49
49
|
|
|
50
50
|
# Serialize a Ruby object to JSON
|
|
@@ -61,11 +61,43 @@ module MultiJSON
|
|
|
61
61
|
return ::JSON.dump(json_object) if options.empty?
|
|
62
62
|
return ::JSON.generate(json_object, options) unless options.key?(:pretty)
|
|
63
63
|
|
|
64
|
+
# ``:pretty`` is MultiJSON's own option, not one the JSON gem's
|
|
65
|
+
# generator understands, so it's stripped rather than passed
|
|
66
|
+
# through. A falsy value asks for compact output, which is what
|
|
67
|
+
# the generator produces with no pretty state at all.
|
|
68
|
+
rest = options.except(:pretty)
|
|
69
|
+
return generate_compact(json_object, rest) unless options[:pretty]
|
|
70
|
+
|
|
64
71
|
# Common case: ``pretty: true`` is the only option, so the merge
|
|
65
72
|
# would just produce a copy of PRETTY_STATE_PROTOTYPE.
|
|
66
|
-
return ::JSON.pretty_generate(json_object, PRETTY_STATE_PROTOTYPE) if
|
|
73
|
+
return ::JSON.pretty_generate(json_object, PRETTY_STATE_PROTOTYPE) if rest.empty?
|
|
74
|
+
|
|
75
|
+
::JSON.pretty_generate(json_object, PRETTY_STATE_PROTOTYPE.merge(rest))
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
private
|
|
79
|
+
|
|
80
|
+
# Serialize a Ruby object to compact JSON
|
|
81
|
+
#
|
|
82
|
+
# Routes through ``::JSON.dump`` when no options remain so that
|
|
83
|
+
# ``pretty: false`` behaves exactly like passing no options at
|
|
84
|
+
# all. ``dump`` applies the permissive ``max_nesting: false`` /
|
|
85
|
+
# ``allow_nan: true`` defaults that ``generate`` does not, so
|
|
86
|
+
# sending the empty-options case to ``generate`` would make
|
|
87
|
+
# ``pretty: false`` raise on deeply nested input that
|
|
88
|
+
# ``MultiJSON.dump(object)`` serializes without complaint.
|
|
89
|
+
#
|
|
90
|
+
# @api private
|
|
91
|
+
# @param json_object [Object] object to serialize
|
|
92
|
+
# @param options [Hash] serialization options, without ``:pretty``
|
|
93
|
+
# @return [String] JSON string
|
|
94
|
+
#
|
|
95
|
+
# @example Serialize without pretty state
|
|
96
|
+
# adapter.send(:generate_compact, {key: "value"}, {}) #=> '{"key":"value"}'
|
|
97
|
+
def generate_compact(json_object, options)
|
|
98
|
+
return ::JSON.dump(json_object) if options.empty?
|
|
67
99
|
|
|
68
|
-
::JSON.
|
|
100
|
+
::JSON.generate(json_object, options)
|
|
69
101
|
end
|
|
70
102
|
end
|
|
71
103
|
end
|
|
@@ -37,7 +37,13 @@ module MultiJSON
|
|
|
37
37
|
def prepare_dump_options(options)
|
|
38
38
|
return options unless options.key?(:pretty)
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
# ``:pretty`` is MultiJSON's own option, so it's dropped either
|
|
41
|
+
# way. A falsy value asks for compact output, which is Oj's
|
|
42
|
+
# behavior without the pretty state merged in.
|
|
43
|
+
rest = options.except(:pretty)
|
|
44
|
+
return rest unless options[:pretty]
|
|
45
|
+
|
|
46
|
+
rest.merge(PRETTY_STATE_PROTOTYPE)
|
|
41
47
|
end
|
|
42
48
|
end
|
|
43
49
|
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Backward-compatible alias for the legacy ``MultiJson`` constant name
|
|
4
|
+
#
|
|
5
|
+
# Downstream code that still writes ``MultiJson.parse(...)`` or
|
|
6
|
+
# ``rescue MultiJson::ParseError`` continues to work, but emits a
|
|
7
|
+
# one-time deprecation warning pointing at ``MultiJSON``. Each public
|
|
8
|
+
# method on {MultiJSON} gets an explicit forwarder defined on this
|
|
9
|
+
# module, and constant access resolves via {.const_missing}, so both
|
|
10
|
+
# dotted calls and ``::`` constant lookups (including rescue clauses)
|
|
11
|
+
# route through the canonical module.
|
|
12
|
+
#
|
|
13
|
+
# This file is loaded last by the ``multi_json`` entry point so the
|
|
14
|
+
# forwarder snapshot below sees the complete {MultiJSON} public API,
|
|
15
|
+
# including the deprecated aliases defined in ``deprecated.rb``.
|
|
16
|
+
#
|
|
17
|
+
# @api public
|
|
18
|
+
# @deprecated Use {MultiJSON} (all-caps) instead. Will be removed in v2.0.
|
|
19
|
+
module MultiJson
|
|
20
|
+
# Forward every public method MultiJSON exposes through an explicit
|
|
21
|
+
# singleton method on the legacy MultiJson module, so callers that
|
|
22
|
+
# capture the method as a Method object (``MultiJson.method(:load)``)
|
|
23
|
+
# find this forwarder instead of falling back to inherited methods like
|
|
24
|
+
# ``Kernel#load``. The earlier ``method_missing``-based shim left
|
|
25
|
+
# ``MultiJson.method(:load)`` resolving to ``Kernel#load`` (because
|
|
26
|
+
# ``Module#method`` doesn't consult ``method_missing``) and broke
|
|
27
|
+
# libraries (Sawyer, Octokit, Danger) that capture decoders as Method
|
|
28
|
+
# objects. Forwarding eagerly fixes the capture path while preserving
|
|
29
|
+
# the one-time deprecation warning each call emits.
|
|
30
|
+
(::MultiJSON.public_methods - ::Module.public_methods).each do |forwarded|
|
|
31
|
+
define_singleton_method(forwarded) do |*args, **kwargs, &block|
|
|
32
|
+
::MultiJSON.warn_deprecation_once(:multi_json_constant,
|
|
33
|
+
"The MultiJson constant is deprecated and will be removed in v2.0. Use MultiJSON instead.")
|
|
34
|
+
::MultiJSON.public_send(forwarded, *args, **kwargs, &block)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
class << self
|
|
39
|
+
# Resolve missing constants to their {MultiJSON} counterparts
|
|
40
|
+
#
|
|
41
|
+
# Enables ``rescue MultiJson::ParseError`` and
|
|
42
|
+
# ``MultiJson::Adapters::Oj`` to keep working during the
|
|
43
|
+
# deprecation cycle.
|
|
44
|
+
#
|
|
45
|
+
# @api public
|
|
46
|
+
# @param name [Symbol] constant name
|
|
47
|
+
# @return [Object] the resolved constant from {MultiJSON}
|
|
48
|
+
# @example
|
|
49
|
+
# MultiJson::ParseError # returns MultiJSON::ParseError
|
|
50
|
+
def const_missing(name)
|
|
51
|
+
::MultiJSON.warn_deprecation_once(:multi_json_constant,
|
|
52
|
+
"The MultiJson constant is deprecated and will be removed in v2.0. Use MultiJSON instead.")
|
|
53
|
+
::MultiJSON.const_get(name)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -17,6 +17,13 @@ module MultiJSON
|
|
|
17
17
|
# via {.max_cache_size=}.
|
|
18
18
|
DEFAULT_MAX_CACHE_SIZE = 1000
|
|
19
19
|
|
|
20
|
+
# Dynamic require path so MRI (mutex_store) and JRuby
|
|
21
|
+
# (concurrent_store) execute the same physical line, avoiding a
|
|
22
|
+
# dead-branch ``require_relative`` that would otherwise drop
|
|
23
|
+
# JRuby's line coverage below 100%.
|
|
24
|
+
BACKENDS = {"jruby" => "concurrent_store"}.freeze
|
|
25
|
+
private_constant :BACKENDS
|
|
26
|
+
|
|
20
27
|
class << self
|
|
21
28
|
# Get the dump options cache
|
|
22
29
|
#
|
|
@@ -71,16 +78,5 @@ module MultiJSON
|
|
|
71
78
|
end
|
|
72
79
|
end
|
|
73
80
|
|
|
74
|
-
module MultiJSON
|
|
75
|
-
module OptionsCache
|
|
76
|
-
# Dynamic require path so MRI (mutex_store) and JRuby
|
|
77
|
-
# (concurrent_store) execute the same physical line, avoiding a
|
|
78
|
-
# dead-branch ``require_relative`` that would otherwise drop
|
|
79
|
-
# JRuby's line coverage below 100%.
|
|
80
|
-
BACKENDS = {"jruby" => "concurrent_store"}.freeze
|
|
81
|
-
private_constant :BACKENDS
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
|
|
85
81
|
require_relative "options_cache/#{MultiJSON::OptionsCache.send(:const_get, :BACKENDS).fetch(RUBY_ENGINE, "mutex_store")}"
|
|
86
82
|
MultiJSON::OptionsCache.reset
|
|
@@ -87,14 +87,19 @@ module MultiJSON
|
|
|
87
87
|
# match can proceed. Strings in binary (ASCII-8BIT) or any valid
|
|
88
88
|
# encoding pass through scrub untouched.
|
|
89
89
|
#
|
|
90
|
+
# The parameter is deliberately not named ``message``: that would
|
|
91
|
+
# shadow ``Exception#message``, which holds the same string once
|
|
92
|
+
# ``super`` has run, and mutation testing could not tell the two
|
|
93
|
+
# apart.
|
|
94
|
+
#
|
|
90
95
|
# @api private
|
|
91
|
-
# @param
|
|
96
|
+
# @param text [String, nil] the adapter's error message
|
|
92
97
|
# @return [MatchData, nil] the regex match, or nil if no message or
|
|
93
98
|
# no location fragment was found
|
|
94
|
-
def location_match(
|
|
95
|
-
return unless
|
|
99
|
+
def location_match(text)
|
|
100
|
+
return unless text
|
|
96
101
|
|
|
97
|
-
LOCATION_PATTERN.match(
|
|
102
|
+
LOCATION_PATTERN.match(text.scrub)
|
|
98
103
|
end
|
|
99
104
|
end
|
|
100
105
|
|
data/lib/multi_json/version.rb
CHANGED
|
@@ -10,7 +10,7 @@ module MultiJSON
|
|
|
10
10
|
# Minor version number
|
|
11
11
|
MINOR = 21 unless defined? MultiJSON::Version::MINOR
|
|
12
12
|
# Patch version number
|
|
13
|
-
PATCH =
|
|
13
|
+
PATCH = 2 unless defined? MultiJSON::Version::PATCH
|
|
14
14
|
# Pre-release version suffix
|
|
15
15
|
PRE = nil unless defined? MultiJSON::Version::PRE
|
|
16
16
|
|
data/lib/multi_json.rb
CHANGED
|
@@ -267,72 +267,4 @@ module MultiJSON
|
|
|
267
267
|
end
|
|
268
268
|
|
|
269
269
|
require_relative "multi_json/deprecated"
|
|
270
|
-
|
|
271
|
-
# Backward-compatible alias for the legacy ``MultiJson`` constant name
|
|
272
|
-
#
|
|
273
|
-
# Downstream code that still writes ``MultiJson.parse(...)`` or
|
|
274
|
-
# ``rescue MultiJson::ParseError`` continues to work, but emits a
|
|
275
|
-
# one-time deprecation warning pointing at ``MultiJSON``. The module
|
|
276
|
-
# forwards every method call to {MultiJSON} via {.method_missing} and
|
|
277
|
-
# resolves constant access via {.const_missing}, so both dotted calls
|
|
278
|
-
# and ``::`` constant lookups (including rescue clauses) route through
|
|
279
|
-
# the canonical module.
|
|
280
|
-
#
|
|
281
|
-
# @api public
|
|
282
|
-
# @deprecated Use {MultiJSON} (all-caps) instead. Will be removed in v2.0.
|
|
283
|
-
module MultiJson
|
|
284
|
-
class << self
|
|
285
|
-
# Forward method calls to {MultiJSON}, emitting a one-time warning
|
|
286
|
-
#
|
|
287
|
-
# Uses explicit ``*args, **kwargs, &block`` forwarding because
|
|
288
|
-
# mutant's AST structure table on the current parser version does
|
|
289
|
-
# not yet recognize ``...`` forwarding nodes, so the module would
|
|
290
|
-
# crash mutation analysis. The rubocop exclusions below document
|
|
291
|
-
# that intent.
|
|
292
|
-
#
|
|
293
|
-
# @api public
|
|
294
|
-
# @return [Object] the delegated call's return value
|
|
295
|
-
# @example
|
|
296
|
-
# MultiJson.parse('{"a":1}') # delegates to MultiJSON.parse
|
|
297
|
-
# rubocop:disable Naming/BlockForwarding, Style/ArgumentsForwarding
|
|
298
|
-
def method_missing(name, *args, **kwargs, &block)
|
|
299
|
-
::MultiJSON.warn_deprecation_once(:multi_json_constant,
|
|
300
|
-
"The MultiJson constant is deprecated and will be removed in v2.0. Use MultiJSON instead.")
|
|
301
|
-
if ::MultiJSON.respond_to?(name)
|
|
302
|
-
::MultiJSON.public_send(name, *args, **kwargs, &block)
|
|
303
|
-
else
|
|
304
|
-
super
|
|
305
|
-
end
|
|
306
|
-
end
|
|
307
|
-
# rubocop:enable Naming/BlockForwarding, Style/ArgumentsForwarding
|
|
308
|
-
|
|
309
|
-
# Respond to any method {MultiJSON} responds to
|
|
310
|
-
#
|
|
311
|
-
# @api public
|
|
312
|
-
# @param name [Symbol] method name
|
|
313
|
-
# @param include_private [Boolean] include private methods
|
|
314
|
-
# @return [Boolean] true if {MultiJSON} responds to the method
|
|
315
|
-
# @example
|
|
316
|
-
# MultiJson.respond_to?(:parse) #=> true
|
|
317
|
-
def respond_to_missing?(name, include_private)
|
|
318
|
-
::MultiJSON.respond_to?(name, include_private)
|
|
319
|
-
end
|
|
320
|
-
|
|
321
|
-
# Resolve missing constants to their {MultiJSON} counterparts
|
|
322
|
-
#
|
|
323
|
-
# Enables ``rescue MultiJson::ParseError`` and
|
|
324
|
-
# ``MultiJson::Adapters::Oj`` to keep working during the
|
|
325
|
-
# deprecation cycle.
|
|
326
|
-
#
|
|
327
|
-
# @api public
|
|
328
|
-
# @param name [Symbol] constant name
|
|
329
|
-
# @return [Object] the resolved constant from {MultiJSON}
|
|
330
|
-
# @example
|
|
331
|
-
# MultiJson::ParseError # returns MultiJSON::ParseError
|
|
332
|
-
def const_missing(name)
|
|
333
|
-
::MultiJSON.warn_deprecation_once(:multi_json_constant,
|
|
334
|
-
"The MultiJson constant is deprecated and will be removed in v2.0. Use MultiJSON instead.")
|
|
335
|
-
::MultiJSON.const_get(name)
|
|
336
|
-
end
|
|
337
|
-
end
|
|
338
|
-
end
|
|
270
|
+
require_relative "multi_json/legacy_constant"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: multi_json
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.21.
|
|
4
|
+
version: 1.21.2
|
|
5
5
|
platform: java
|
|
6
6
|
authors:
|
|
7
7
|
- Michael Bleigh
|
|
@@ -49,6 +49,7 @@ files:
|
|
|
49
49
|
- lib/multi_json/adapters/yajl.rb
|
|
50
50
|
- lib/multi_json/concurrency.rb
|
|
51
51
|
- lib/multi_json/deprecated.rb
|
|
52
|
+
- lib/multi_json/legacy_constant.rb
|
|
52
53
|
- lib/multi_json/options.rb
|
|
53
54
|
- lib/multi_json/options_cache.rb
|
|
54
55
|
- lib/multi_json/options_cache/concurrent_store.rb
|
|
@@ -59,10 +60,10 @@ licenses:
|
|
|
59
60
|
- MIT
|
|
60
61
|
metadata:
|
|
61
62
|
bug_tracker_uri: https://github.com/sferik/multi_json/issues
|
|
62
|
-
changelog_uri: https://github.com/sferik/multi_json/blob/v1.21.
|
|
63
|
-
documentation_uri: https://www.rubydoc.info/gems/multi_json/1.21.
|
|
63
|
+
changelog_uri: https://github.com/sferik/multi_json/blob/v1.21.2/CHANGELOG.md
|
|
64
|
+
documentation_uri: https://www.rubydoc.info/gems/multi_json/1.21.2
|
|
64
65
|
rubygems_mfa_required: 'true'
|
|
65
|
-
source_code_uri: https://github.com/sferik/multi_json/tree/v1.21.
|
|
66
|
+
source_code_uri: https://github.com/sferik/multi_json/tree/v1.21.2
|
|
66
67
|
wiki_uri: https://github.com/sferik/multi_json/wiki
|
|
67
68
|
rdoc_options: []
|
|
68
69
|
require_paths:
|
|
@@ -78,7 +79,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
78
79
|
- !ruby/object:Gem::Version
|
|
79
80
|
version: '0'
|
|
80
81
|
requirements: []
|
|
81
|
-
rubygems_version: 4.0.
|
|
82
|
+
rubygems_version: 4.0.20
|
|
82
83
|
specification_version: 4
|
|
83
84
|
summary: A common interface to multiple JSON libraries.
|
|
84
85
|
test_files: []
|