multi_json 1.19.1 → 1.21.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 +4 -4
- data/LICENSE.md +1 -1
- data/README.md +199 -36
- data/lib/multi_json/adapter.rb +137 -20
- data/lib/multi_json/adapter_error.rb +11 -2
- data/lib/multi_json/adapter_selector.rb +119 -47
- data/lib/multi_json/adapters/fast_jsonparser.rb +53 -23
- data/lib/multi_json/adapters/json_gem.rb +23 -10
- data/lib/multi_json/adapters/oj.rb +35 -12
- data/lib/multi_json/adapters/oj_common.rb +25 -28
- data/lib/multi_json/adapters/yajl.rb +5 -2
- data/lib/multi_json/concurrency.rb +57 -0
- data/lib/multi_json/deprecated.rb +113 -0
- data/lib/multi_json/options.rb +128 -28
- data/lib/multi_json/options_cache/mutex_store.rb +65 -0
- data/lib/multi_json/options_cache.rb +54 -66
- data/lib/multi_json/parse_error.rb +60 -3
- data/lib/multi_json/version.rb +8 -6
- data/lib/multi_json.rb +221 -136
- metadata +10 -14
- data/CHANGELOG.md +0 -228
- data/CONTRIBUTING.md +0 -52
- data/lib/multi_json/adapters/gson.rb +0 -37
- data/lib/multi_json/adapters/jr_jackson.rb +0 -52
- data/lib/multi_json/adapters/ok_json.rb +0 -43
- data/lib/multi_json/convertible_hash_keys.rb +0 -66
- data/lib/multi_json/vendor/okjson.rb +0 -545
data/lib/multi_json.rb
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "multi_json/concurrency"
|
|
1
4
|
require_relative "multi_json/options"
|
|
2
5
|
require_relative "multi_json/version"
|
|
3
6
|
require_relative "multi_json/adapter_error"
|
|
@@ -7,229 +10,311 @@ require_relative "multi_json/adapter_selector"
|
|
|
7
10
|
|
|
8
11
|
# A unified interface for JSON libraries in Ruby
|
|
9
12
|
#
|
|
10
|
-
#
|
|
13
|
+
# MultiJSON allows swapping between JSON backends without changing your code.
|
|
11
14
|
# It auto-detects available JSON libraries and uses the fastest one available.
|
|
12
15
|
#
|
|
16
|
+
# ## Method-definition patterns
|
|
17
|
+
#
|
|
18
|
+
# The current public API uses two patterns, each chosen for a specific reason:
|
|
19
|
+
#
|
|
20
|
+
# 1. ``module_function`` creates both a class method and a private instance
|
|
21
|
+
# method from a single ``def``. This is used for the hot-path API
|
|
22
|
+
# (``adapter``, ``use``, ``adapter=``, ``parse``, ``generate``,
|
|
23
|
+
# ``current_adapter``) so that both ``MultiJSON.parse(...)`` and legacy
|
|
24
|
+
# ``Class.new { include MultiJSON }.new.send(:parse, ...)`` invocations
|
|
25
|
+
# work through the same body. The instance versions are re-publicized
|
|
26
|
+
# below so YARD renders them as part of the public API.
|
|
27
|
+
# 2. ``def self.foo`` creates only a singleton method, giving mutation
|
|
28
|
+
# testing a single canonical definition to target. This is used for
|
|
29
|
+
# {.with_adapter}, which needs precise mutation coverage of its
|
|
30
|
+
# fiber-local save/restore logic.
|
|
31
|
+
#
|
|
32
|
+
# Deprecated public API (``decode``, ``encode``, ``engine``, ``load``,
|
|
33
|
+
# ``dump``, etc.) lives in {file:lib/multi_json/deprecated.rb} so this
|
|
34
|
+
# file stays focused on the current surface.
|
|
35
|
+
#
|
|
13
36
|
# @example Basic usage
|
|
14
|
-
#
|
|
15
|
-
#
|
|
37
|
+
# MultiJSON.parse('{"foo":"bar"}') #=> {"foo" => "bar"}
|
|
38
|
+
# MultiJSON.generate({foo: "bar"}) #=> '{"foo":"bar"}'
|
|
16
39
|
#
|
|
17
40
|
# @example Specifying an adapter
|
|
18
|
-
#
|
|
19
|
-
#
|
|
41
|
+
# MultiJSON.use(:oj)
|
|
42
|
+
# MultiJSON.parse('{"foo":"bar"}', adapter: :json_gem)
|
|
20
43
|
#
|
|
21
44
|
# @api public
|
|
22
|
-
module
|
|
45
|
+
module MultiJSON
|
|
23
46
|
extend Options
|
|
24
47
|
extend AdapterSelector
|
|
25
48
|
|
|
26
|
-
#
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
49
|
+
# Tracks which deprecation warnings have already been emitted so each one
|
|
50
|
+
# fires at most once per process. Stored as a Set rather than a Hash so
|
|
51
|
+
# presence checks have unambiguous semantics for mutation tests.
|
|
52
|
+
DEPRECATION_WARNINGS_SHOWN = Set.new
|
|
53
|
+
private_constant :DEPRECATION_WARNINGS_SHOWN
|
|
30
54
|
|
|
31
|
-
#
|
|
55
|
+
# Emit a deprecation warning at most once per process for the given key
|
|
32
56
|
#
|
|
33
|
-
#
|
|
34
|
-
#
|
|
35
|
-
#
|
|
36
|
-
#
|
|
37
|
-
#
|
|
38
|
-
#
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
# Get the default options
|
|
57
|
+
# Defined as a singleton method (rather than via module_function) so
|
|
58
|
+
# there is exactly one definition for mutation tests to target.
|
|
59
|
+
# Public so the deprecated ``load_options`` / ``dump_options``
|
|
60
|
+
# aliases on the {Options} mixin can invoke it without routing
|
|
61
|
+
# through ``MultiJSON.send(...)``.
|
|
62
|
+
#
|
|
63
|
+
# The warning is tagged with the ``:deprecated`` category so callers
|
|
64
|
+
# can silence the whole set with ``Warning[:deprecated] = false`` or
|
|
65
|
+
# surface it via ``ruby -W:deprecated`` — the standard Ruby idiom for
|
|
66
|
+
# library deprecations since 2.7.
|
|
46
67
|
#
|
|
47
68
|
# @api private
|
|
48
|
-
# @
|
|
49
|
-
# @
|
|
69
|
+
# @param key [Symbol] identifier for the deprecation (typically the method name)
|
|
70
|
+
# @param message [String] warning message to emit on first call
|
|
71
|
+
# @return [void]
|
|
50
72
|
# @example
|
|
51
|
-
#
|
|
52
|
-
def
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
load_options
|
|
56
|
-
end
|
|
73
|
+
# MultiJSON.warn_deprecation_once(:foo, "MultiJSON.foo is deprecated")
|
|
74
|
+
def self.warn_deprecation_once(key, message)
|
|
75
|
+
Concurrency.synchronize(:deprecation_warnings) do
|
|
76
|
+
return if DEPRECATION_WARNINGS_SHOWN.include?(key)
|
|
57
77
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
define_method(method_name) do |*|
|
|
61
|
-
Kernel.warn "MultiJson.#{method_name} method is deprecated and no longer used."
|
|
78
|
+
Kernel.warn(message, category: :deprecated)
|
|
79
|
+
DEPRECATION_WARNINGS_SHOWN.add(key)
|
|
62
80
|
end
|
|
63
81
|
end
|
|
64
82
|
|
|
65
|
-
#
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
#
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
83
|
+
# Resolve the ``ParseError`` constant for an adapter class
|
|
84
|
+
#
|
|
85
|
+
# The result is memoized on the adapter class itself in a
|
|
86
|
+
# ``@_multi_json_parse_error`` ivar so subsequent ``MultiJSON.load``
|
|
87
|
+
# calls skip the constant lookup entirely. The lookup is performed
|
|
88
|
+
# with ``inherit: false`` so a stray top-level ``::ParseError``
|
|
89
|
+
# constant in the host process is correctly ignored on every
|
|
90
|
+
# supported Ruby implementation — TruffleRuby's ``::`` operator
|
|
91
|
+
# walks the ancestor chain and would otherwise pick up the top-level
|
|
92
|
+
# constant. Custom adapters that don't define their own
|
|
93
|
+
# ``ParseError`` get a clear {AdapterError} instead of the bare
|
|
94
|
+
# ``NameError`` Ruby would raise from the rescue clause.
|
|
95
|
+
#
|
|
96
|
+
# @api private
|
|
97
|
+
# @param adapter_class [Class] adapter class to inspect
|
|
98
|
+
# @return [Class] the adapter's ParseError class
|
|
99
|
+
# @raise [AdapterError] when the adapter doesn't define ParseError
|
|
100
|
+
def self.parse_error_class_for(adapter_class)
|
|
101
|
+
cached = adapter_class.instance_variable_get(:@_multi_json_parse_error)
|
|
102
|
+
return cached if cached
|
|
77
103
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
#
|
|
82
|
-
# @deprecated Use {.default_adapter} instead
|
|
83
|
-
# @return [Symbol] the default adapter name
|
|
84
|
-
# @example
|
|
85
|
-
# MultiJson.default_engine #=> :oj
|
|
86
|
-
alias_method :default_engine, :default_adapter
|
|
104
|
+
resolved = adapter_class.const_get(:ParseError, false)
|
|
105
|
+
adapter_class.instance_variable_set(:@_multi_json_parse_error, resolved)
|
|
106
|
+
rescue NameError
|
|
107
|
+
raise AdapterError, "Adapter #{adapter_class} must define a ParseError constant"
|
|
87
108
|
end
|
|
88
109
|
|
|
89
|
-
#
|
|
110
|
+
# ===========================================================================
|
|
111
|
+
# Public API (module_function: class + private instance method)
|
|
112
|
+
# ===========================================================================
|
|
90
113
|
|
|
91
|
-
# @!
|
|
114
|
+
# @!visibility private
|
|
115
|
+
module_function
|
|
92
116
|
|
|
93
117
|
# Returns the current adapter class
|
|
94
118
|
#
|
|
95
|
-
#
|
|
119
|
+
# Honors a fiber-local override set by {.with_adapter} so concurrent
|
|
120
|
+
# blocks observe their own adapter without clobbering the process-wide
|
|
121
|
+
# default. Falls back to the process default when no override is set.
|
|
122
|
+
#
|
|
123
|
+
# @api public
|
|
96
124
|
# @return [Class] the current adapter class
|
|
97
125
|
# @example
|
|
98
|
-
#
|
|
126
|
+
# MultiJSON.adapter #=> MultiJSON::Adapters::Oj
|
|
99
127
|
def adapter
|
|
128
|
+
override = Fiber[:multi_json_adapter]
|
|
129
|
+
return override if override
|
|
130
|
+
|
|
100
131
|
@adapter ||= use(nil)
|
|
101
132
|
end
|
|
102
133
|
|
|
103
|
-
# Returns the current adapter class (alias for adapter)
|
|
104
|
-
#
|
|
105
|
-
# @api private
|
|
106
|
-
# @deprecated Use {.adapter} instead
|
|
107
|
-
# @return [Class] the current adapter class
|
|
108
|
-
# @example
|
|
109
|
-
# MultiJson.engine #=> MultiJson::Adapters::Oj
|
|
110
|
-
alias_method :engine, :adapter
|
|
111
|
-
|
|
112
134
|
# Sets the adapter to use for JSON operations
|
|
113
135
|
#
|
|
114
|
-
#
|
|
136
|
+
# The merged-options cache is only reset when the new adapter loads
|
|
137
|
+
# successfully. A failed ``use(:nonexistent)`` leaves the cache in
|
|
138
|
+
# place so the previously-active adapter keeps its cached entries.
|
|
139
|
+
#
|
|
140
|
+
# @api public
|
|
115
141
|
# @param new_adapter [Symbol, String, Module, nil] adapter specification
|
|
116
142
|
# @return [Class] the loaded adapter class
|
|
117
143
|
# @example
|
|
118
|
-
#
|
|
144
|
+
# MultiJSON.use(:oj)
|
|
119
145
|
def use(new_adapter)
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
146
|
+
loaded = load_adapter(new_adapter)
|
|
147
|
+
Concurrency.synchronize(:adapter) do
|
|
148
|
+
OptionsCache.reset
|
|
149
|
+
@adapter = loaded
|
|
150
|
+
end
|
|
123
151
|
end
|
|
124
152
|
|
|
125
153
|
# Sets the adapter to use for JSON operations
|
|
126
154
|
#
|
|
127
|
-
# @api
|
|
155
|
+
# @api public
|
|
128
156
|
# @return [Class] the loaded adapter class
|
|
129
157
|
# @example
|
|
130
|
-
#
|
|
158
|
+
# MultiJSON.adapter = :json_gem
|
|
131
159
|
alias_method :adapter=, :use
|
|
132
|
-
|
|
133
|
-
# Sets the adapter to use for JSON operations
|
|
134
|
-
#
|
|
135
|
-
# @api private
|
|
136
|
-
# @deprecated Use {.adapter=} instead
|
|
137
|
-
# @return [Class] the loaded adapter class
|
|
138
|
-
# @example
|
|
139
|
-
# MultiJson.engine = :json_gem
|
|
140
|
-
alias_method :engine=, :use
|
|
141
|
-
module_function :adapter=, :engine=
|
|
142
|
-
|
|
143
|
-
# @!endgroup
|
|
144
|
-
|
|
145
|
-
# @!group JSON Operations
|
|
160
|
+
module_function :adapter=
|
|
146
161
|
|
|
147
162
|
# Parses a JSON string into a Ruby object
|
|
148
163
|
#
|
|
149
|
-
#
|
|
164
|
+
# Returns ``nil`` for ``nil``, empty, and whitespace-only inputs
|
|
165
|
+
# instead of raising. Pass an explicit non-blank string if you want
|
|
166
|
+
# to surface a {ParseError} for empty payloads at the call site.
|
|
167
|
+
#
|
|
168
|
+
# @api public
|
|
150
169
|
# @param string [String, #read] JSON string or IO-like object
|
|
151
170
|
# @param options [Hash] parsing options (adapter-specific)
|
|
152
|
-
# @return [Object] parsed Ruby object
|
|
171
|
+
# @return [Object, nil] parsed Ruby object, or nil for blank input
|
|
153
172
|
# @raise [ParseError] if parsing fails
|
|
173
|
+
# @raise [AdapterError] if the adapter doesn't define a ``ParseError`` constant
|
|
154
174
|
# @example
|
|
155
|
-
#
|
|
156
|
-
|
|
175
|
+
# MultiJSON.parse('{"foo":"bar"}') #=> {"foo" => "bar"}
|
|
176
|
+
# MultiJSON.parse("") #=> nil
|
|
177
|
+
# MultiJSON.parse(" \n") #=> nil
|
|
178
|
+
def parse(string, options = {})
|
|
157
179
|
adapter_class = current_adapter(options)
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
180
|
+
parse_error_class = MultiJSON.parse_error_class_for(adapter_class)
|
|
181
|
+
begin
|
|
182
|
+
adapter_class.load(string, options)
|
|
183
|
+
rescue parse_error_class => e
|
|
184
|
+
raise ParseError.build(e, string)
|
|
185
|
+
end
|
|
161
186
|
end
|
|
162
187
|
|
|
163
|
-
# Parses a JSON string into a Ruby object
|
|
164
|
-
#
|
|
165
|
-
# @api private
|
|
166
|
-
# @deprecated Use {.load} instead
|
|
167
|
-
# @return [Object] parsed Ruby object
|
|
168
|
-
# @example
|
|
169
|
-
# MultiJson.decode('{"foo":"bar"}') #=> {"foo" => "bar"}
|
|
170
|
-
alias_method :decode, :load
|
|
171
|
-
module_function :decode
|
|
172
|
-
|
|
173
188
|
# Returns the adapter to use for the given options
|
|
174
189
|
#
|
|
175
|
-
#
|
|
176
|
-
#
|
|
190
|
+
# ``nil`` is accepted as a no-options sentinel — explicit
|
|
191
|
+
# ``current_adapter(nil)`` calls fall through to the process default
|
|
192
|
+
# adapter without raising.
|
|
193
|
+
#
|
|
194
|
+
# @api public
|
|
195
|
+
# @param options [Hash, nil] options that may contain :adapter key, or
|
|
196
|
+
# nil to use the process default
|
|
177
197
|
# @return [Class] adapter class
|
|
178
198
|
# @example
|
|
179
|
-
#
|
|
199
|
+
# MultiJSON.current_adapter(adapter: :oj) #=> MultiJSON::Adapters::Oj
|
|
180
200
|
def current_adapter(options = {})
|
|
181
|
-
options ||=
|
|
201
|
+
options ||= Options::EMPTY_OPTIONS
|
|
182
202
|
adapter_override = options[:adapter]
|
|
183
203
|
adapter_override ? load_adapter(adapter_override) : adapter
|
|
184
204
|
end
|
|
185
205
|
|
|
186
206
|
# Serializes a Ruby object to a JSON string
|
|
187
207
|
#
|
|
188
|
-
# @api
|
|
208
|
+
# @api public
|
|
189
209
|
# @param object [Object] object to serialize
|
|
190
210
|
# @param options [Hash] serialization options (adapter-specific)
|
|
191
211
|
# @return [String] JSON string
|
|
192
212
|
# @example
|
|
193
|
-
#
|
|
194
|
-
def
|
|
213
|
+
# MultiJSON.generate({foo: "bar"}) #=> '{"foo":"bar"}'
|
|
214
|
+
def generate(object, options = {})
|
|
195
215
|
current_adapter(options).dump(object, options)
|
|
196
216
|
end
|
|
197
217
|
|
|
198
|
-
#
|
|
199
|
-
#
|
|
200
|
-
#
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
#
|
|
204
|
-
#
|
|
205
|
-
|
|
206
|
-
module_function :encode
|
|
218
|
+
# Re-publicize the instance versions of the module_function methods so
|
|
219
|
+
# YARD/yardstick render them as part of the public API and legacy
|
|
220
|
+
# ``include MultiJSON`` consumers can call them without ``.send``.
|
|
221
|
+
public :adapter, :use, :adapter=, :parse, :current_adapter, :generate
|
|
222
|
+
|
|
223
|
+
# ===========================================================================
|
|
224
|
+
# Public API (def self.foo: singleton-only, for mutation-test precision)
|
|
225
|
+
# ===========================================================================
|
|
207
226
|
|
|
208
227
|
# Executes a block using the specified adapter
|
|
209
228
|
#
|
|
210
|
-
#
|
|
229
|
+
# Defined as a singleton method so mutation testing has exactly one
|
|
230
|
+
# definition to target. The override is stored in fiber-local storage
|
|
231
|
+
# so concurrent fibers and threads each see their own adapter without
|
|
232
|
+
# racing on a shared module variable; nested calls save and restore
|
|
233
|
+
# the previous fiber-local value.
|
|
234
|
+
#
|
|
235
|
+
# @api public
|
|
211
236
|
# @param new_adapter [Symbol, String, Module] adapter to use
|
|
212
237
|
# @yield block to execute with the temporary adapter
|
|
213
238
|
# @return [Object] result of the block
|
|
214
239
|
# @example
|
|
215
|
-
#
|
|
216
|
-
def with_adapter(new_adapter)
|
|
217
|
-
|
|
218
|
-
|
|
240
|
+
# MultiJSON.with_adapter(:json_gem) { MultiJSON.dump({}) }
|
|
241
|
+
def self.with_adapter(new_adapter)
|
|
242
|
+
previous_override = Fiber[:multi_json_adapter]
|
|
243
|
+
Fiber[:multi_json_adapter] = load_adapter(new_adapter)
|
|
219
244
|
yield
|
|
220
245
|
ensure
|
|
221
|
-
|
|
246
|
+
Fiber[:multi_json_adapter] = previous_override
|
|
222
247
|
end
|
|
223
248
|
|
|
224
|
-
#
|
|
249
|
+
# ===========================================================================
|
|
250
|
+
# Private instance-method delegates for the singleton-only methods above
|
|
251
|
+
# ===========================================================================
|
|
252
|
+
|
|
253
|
+
private
|
|
254
|
+
|
|
255
|
+
# Instance-method delegate for {MultiJSON.with_adapter}
|
|
225
256
|
#
|
|
226
257
|
# @api private
|
|
227
|
-
# @
|
|
258
|
+
# @param new_adapter [Symbol, String, Module] adapter to use
|
|
259
|
+
# @yield block to execute with the temporary adapter
|
|
228
260
|
# @return [Object] result of the block
|
|
229
261
|
# @example
|
|
230
|
-
#
|
|
231
|
-
|
|
232
|
-
|
|
262
|
+
# class Foo; include MultiJSON; end
|
|
263
|
+
# Foo.new.send(:with_adapter, :json_gem) { ... }
|
|
264
|
+
def with_adapter(new_adapter, &)
|
|
265
|
+
MultiJSON.with_adapter(new_adapter, &)
|
|
266
|
+
end
|
|
267
|
+
end
|
|
233
268
|
|
|
234
|
-
|
|
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``. Each public
|
|
276
|
+
# method on {MultiJSON} gets an explicit forwarder defined on this
|
|
277
|
+
# module, and constant access resolves via {.const_missing}, so both
|
|
278
|
+
# dotted calls and ``::`` constant lookups (including rescue clauses)
|
|
279
|
+
# route through the canonical module.
|
|
280
|
+
#
|
|
281
|
+
# @api public
|
|
282
|
+
# @deprecated Use {MultiJSON} (all-caps) instead. Will be removed in v2.0.
|
|
283
|
+
module MultiJson
|
|
284
|
+
# Forward every public method MultiJSON exposes through an explicit
|
|
285
|
+
# singleton method on the legacy MultiJson module, so callers that
|
|
286
|
+
# capture the method as a Method object (``MultiJson.method(:load)``)
|
|
287
|
+
# find this forwarder instead of falling back to inherited methods like
|
|
288
|
+
# ``Kernel#load``. The earlier ``method_missing``-based shim left
|
|
289
|
+
# ``MultiJson.method(:load)`` resolving to ``Kernel#load`` (because
|
|
290
|
+
# ``Module#method`` doesn't consult ``method_missing``) and broke
|
|
291
|
+
# libraries (Sawyer, Octokit, Danger) that capture decoders as Method
|
|
292
|
+
# objects. Forwarding eagerly fixes the capture path while preserving
|
|
293
|
+
# the one-time deprecation warning each call emits.
|
|
294
|
+
(::MultiJSON.public_methods - ::Module.public_methods).each do |forwarded|
|
|
295
|
+
define_singleton_method(forwarded) do |*args, **kwargs, &block|
|
|
296
|
+
::MultiJSON.warn_deprecation_once(:multi_json_constant,
|
|
297
|
+
"The MultiJson constant is deprecated and will be removed in v2.0. Use MultiJSON instead.")
|
|
298
|
+
::MultiJSON.public_send(forwarded, *args, **kwargs, &block)
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
class << self
|
|
303
|
+
# Resolve missing constants to their {MultiJSON} counterparts
|
|
304
|
+
#
|
|
305
|
+
# Enables ``rescue MultiJson::ParseError`` and
|
|
306
|
+
# ``MultiJson::Adapters::Oj`` to keep working during the
|
|
307
|
+
# deprecation cycle.
|
|
308
|
+
#
|
|
309
|
+
# @api public
|
|
310
|
+
# @param name [Symbol] constant name
|
|
311
|
+
# @return [Object] the resolved constant from {MultiJSON}
|
|
312
|
+
# @example
|
|
313
|
+
# MultiJson::ParseError # returns MultiJSON::ParseError
|
|
314
|
+
def const_missing(name)
|
|
315
|
+
::MultiJSON.warn_deprecation_once(:multi_json_constant,
|
|
316
|
+
"The MultiJson constant is deprecated and will be removed in v2.0. Use MultiJSON instead.")
|
|
317
|
+
::MultiJSON.const_get(name)
|
|
318
|
+
end
|
|
319
|
+
end
|
|
235
320
|
end
|
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.
|
|
4
|
+
version: 1.21.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Michael Bleigh
|
|
@@ -13,15 +13,13 @@ cert_chain: []
|
|
|
13
13
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
14
14
|
dependencies: []
|
|
15
15
|
description: A common interface to multiple JSON libraries, including fast_jsonparser,
|
|
16
|
-
Oj, Yajl, the JSON gem
|
|
16
|
+
Oj, Yajl, and the JSON gem.
|
|
17
17
|
email:
|
|
18
18
|
- sferik@gmail.com
|
|
19
19
|
executables: []
|
|
20
20
|
extensions: []
|
|
21
21
|
extra_rdoc_files: []
|
|
22
22
|
files:
|
|
23
|
-
- CHANGELOG.md
|
|
24
|
-
- CONTRIBUTING.md
|
|
25
23
|
- LICENSE.md
|
|
26
24
|
- README.md
|
|
27
25
|
- lib/multi_json.rb
|
|
@@ -29,28 +27,26 @@ files:
|
|
|
29
27
|
- lib/multi_json/adapter_error.rb
|
|
30
28
|
- lib/multi_json/adapter_selector.rb
|
|
31
29
|
- lib/multi_json/adapters/fast_jsonparser.rb
|
|
32
|
-
- lib/multi_json/adapters/gson.rb
|
|
33
|
-
- lib/multi_json/adapters/jr_jackson.rb
|
|
34
30
|
- lib/multi_json/adapters/json_gem.rb
|
|
35
31
|
- lib/multi_json/adapters/oj.rb
|
|
36
32
|
- lib/multi_json/adapters/oj_common.rb
|
|
37
|
-
- lib/multi_json/adapters/ok_json.rb
|
|
38
33
|
- lib/multi_json/adapters/yajl.rb
|
|
39
|
-
- lib/multi_json/
|
|
34
|
+
- lib/multi_json/concurrency.rb
|
|
35
|
+
- lib/multi_json/deprecated.rb
|
|
40
36
|
- lib/multi_json/options.rb
|
|
41
37
|
- lib/multi_json/options_cache.rb
|
|
38
|
+
- lib/multi_json/options_cache/mutex_store.rb
|
|
42
39
|
- lib/multi_json/parse_error.rb
|
|
43
|
-
- lib/multi_json/vendor/okjson.rb
|
|
44
40
|
- lib/multi_json/version.rb
|
|
45
41
|
homepage: https://github.com/sferik/multi_json
|
|
46
42
|
licenses:
|
|
47
43
|
- MIT
|
|
48
44
|
metadata:
|
|
49
45
|
bug_tracker_uri: https://github.com/sferik/multi_json/issues
|
|
50
|
-
changelog_uri: https://github.com/sferik/multi_json/blob/v1.
|
|
51
|
-
documentation_uri: https://www.rubydoc.info/gems/multi_json/1.
|
|
46
|
+
changelog_uri: https://github.com/sferik/multi_json/blob/v1.21.1/CHANGELOG.md
|
|
47
|
+
documentation_uri: https://www.rubydoc.info/gems/multi_json/1.21.1
|
|
52
48
|
rubygems_mfa_required: 'true'
|
|
53
|
-
source_code_uri: https://github.com/sferik/multi_json/tree/v1.
|
|
49
|
+
source_code_uri: https://github.com/sferik/multi_json/tree/v1.21.1
|
|
54
50
|
wiki_uri: https://github.com/sferik/multi_json/wiki
|
|
55
51
|
rdoc_options: []
|
|
56
52
|
require_paths:
|
|
@@ -59,14 +55,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
59
55
|
requirements:
|
|
60
56
|
- - ">="
|
|
61
57
|
- !ruby/object:Gem::Version
|
|
62
|
-
version: '3.
|
|
58
|
+
version: '3.2'
|
|
63
59
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
64
60
|
requirements:
|
|
65
61
|
- - ">="
|
|
66
62
|
- !ruby/object:Gem::Version
|
|
67
63
|
version: '0'
|
|
68
64
|
requirements: []
|
|
69
|
-
rubygems_version: 4.0.
|
|
65
|
+
rubygems_version: 4.0.11
|
|
70
66
|
specification_version: 4
|
|
71
67
|
summary: A common interface to multiple JSON libraries.
|
|
72
68
|
test_files: []
|