ed-precompiled_json 2.15.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.
@@ -0,0 +1,708 @@
1
+ # frozen_string_literal: true
2
+ module JSON
3
+ module TruffleRuby
4
+ module Generator
5
+ MAP = {
6
+ "\x0" => '\u0000',
7
+ "\x1" => '\u0001',
8
+ "\x2" => '\u0002',
9
+ "\x3" => '\u0003',
10
+ "\x4" => '\u0004',
11
+ "\x5" => '\u0005',
12
+ "\x6" => '\u0006',
13
+ "\x7" => '\u0007',
14
+ "\b" => '\b',
15
+ "\t" => '\t',
16
+ "\n" => '\n',
17
+ "\xb" => '\u000b',
18
+ "\f" => '\f',
19
+ "\r" => '\r',
20
+ "\xe" => '\u000e',
21
+ "\xf" => '\u000f',
22
+ "\x10" => '\u0010',
23
+ "\x11" => '\u0011',
24
+ "\x12" => '\u0012',
25
+ "\x13" => '\u0013',
26
+ "\x14" => '\u0014',
27
+ "\x15" => '\u0015',
28
+ "\x16" => '\u0016',
29
+ "\x17" => '\u0017',
30
+ "\x18" => '\u0018',
31
+ "\x19" => '\u0019',
32
+ "\x1a" => '\u001a',
33
+ "\x1b" => '\u001b',
34
+ "\x1c" => '\u001c',
35
+ "\x1d" => '\u001d',
36
+ "\x1e" => '\u001e',
37
+ "\x1f" => '\u001f',
38
+ '"' => '\"',
39
+ '\\' => '\\\\',
40
+ }.freeze # :nodoc:
41
+
42
+ SCRIPT_SAFE_MAP = MAP.merge(
43
+ '/' => '\\/',
44
+ "\u2028" => '\u2028',
45
+ "\u2029" => '\u2029',
46
+ ).freeze
47
+
48
+ SCRIPT_SAFE_ESCAPE_PATTERN = /[\/"\\\x0-\x1f\u2028-\u2029]/
49
+
50
+ def self.native_type?(value) # :nodoc:
51
+ (false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value)
52
+ end
53
+
54
+ def self.native_key?(key) # :nodoc:
55
+ (Symbol === key || String === key)
56
+ end
57
+
58
+ # Convert a UTF8 encoded Ruby string _string_ to a JSON string, encoded with
59
+ # UTF16 big endian characters as \u????, and return it.
60
+ def self.utf8_to_json(string, script_safe = false) # :nodoc:
61
+ if script_safe
62
+ if SCRIPT_SAFE_ESCAPE_PATTERN.match?(string)
63
+ string.gsub(SCRIPT_SAFE_ESCAPE_PATTERN, SCRIPT_SAFE_MAP)
64
+ else
65
+ string
66
+ end
67
+ else
68
+ if /["\\\x0-\x1f]/.match?(string)
69
+ string.gsub(/["\\\x0-\x1f]/, MAP)
70
+ else
71
+ string
72
+ end
73
+ end
74
+ end
75
+
76
+ def self.utf8_to_json_ascii(original_string, script_safe = false) # :nodoc:
77
+ string = original_string.b
78
+ map = script_safe ? SCRIPT_SAFE_MAP : MAP
79
+ string.gsub!(/[\/"\\\x0-\x1f]/n) { map[$&] || $& }
80
+ string.gsub!(/(
81
+ (?:
82
+ [\xc2-\xdf][\x80-\xbf] |
83
+ [\xe0-\xef][\x80-\xbf]{2} |
84
+ [\xf0-\xf4][\x80-\xbf]{3}
85
+ )+ |
86
+ [\x80-\xc1\xf5-\xff] # invalid
87
+ )/nx) { |c|
88
+ c.size == 1 and raise GeneratorError.new("invalid utf8 byte: '#{c}'", original_string)
89
+ s = c.encode(::Encoding::UTF_16BE, ::Encoding::UTF_8).unpack('H*')[0]
90
+ s.force_encoding(::Encoding::BINARY)
91
+ s.gsub!(/.{4}/n, '\\\\u\&')
92
+ s.force_encoding(::Encoding::UTF_8)
93
+ }
94
+ string.force_encoding(::Encoding::UTF_8)
95
+ string
96
+ rescue => e
97
+ raise GeneratorError.new(e.message, original_string)
98
+ end
99
+
100
+ def self.valid_utf8?(string)
101
+ encoding = string.encoding
102
+ (encoding == Encoding::UTF_8 || encoding == Encoding::ASCII) &&
103
+ string.valid_encoding?
104
+ end
105
+
106
+ # This class is used to create State instances, that are use to hold data
107
+ # while generating a JSON text from a Ruby data structure.
108
+ class State
109
+ def self.generate(obj, opts = nil, io = nil)
110
+ new(opts).generate(obj, io)
111
+ end
112
+
113
+ # Creates a State object from _opts_, which ought to be Hash to create
114
+ # a new State instance configured by _opts_, something else to create
115
+ # an unconfigured instance. If _opts_ is a State object, it is just
116
+ # returned.
117
+ def self.from_state(opts)
118
+ if opts
119
+ case
120
+ when self === opts
121
+ return opts
122
+ when opts.respond_to?(:to_hash)
123
+ return new(opts.to_hash)
124
+ when opts.respond_to?(:to_h)
125
+ return new(opts.to_h)
126
+ end
127
+ end
128
+ new
129
+ end
130
+
131
+ # Instantiates a new State object, configured by _opts_.
132
+ #
133
+ # _opts_ can have the following keys:
134
+ #
135
+ # * *indent*: a string used to indent levels (default: ''),
136
+ # * *space*: a string that is put after, a : or , delimiter (default: ''),
137
+ # * *space_before*: a string that is put before a : pair delimiter (default: ''),
138
+ # * *object_nl*: a string that is put at the end of a JSON object (default: ''),
139
+ # * *array_nl*: a string that is put at the end of a JSON array (default: ''),
140
+ # * *script_safe*: true if U+2028, U+2029 and forward slash (/) should be escaped
141
+ # as to make the JSON object safe to interpolate in a script tag (default: false).
142
+ # * *check_circular*: is deprecated now, use the :max_nesting option instead,
143
+ # * *max_nesting*: sets the maximum level of data structure nesting in
144
+ # the generated JSON, max_nesting = 0 if no maximum should be checked.
145
+ # * *allow_nan*: true if NaN, Infinity, and -Infinity should be
146
+ # generated, otherwise an exception is thrown, if these values are
147
+ # encountered. This options defaults to false.
148
+ def initialize(opts = nil)
149
+ @indent = ''
150
+ @space = ''
151
+ @space_before = ''
152
+ @object_nl = ''
153
+ @array_nl = ''
154
+ @allow_nan = false
155
+ @ascii_only = false
156
+ @as_json = false
157
+ @depth = 0
158
+ @buffer_initial_length = 1024
159
+ @script_safe = false
160
+ @strict = false
161
+ @max_nesting = 100
162
+ configure(opts) if opts
163
+ end
164
+
165
+ # This string is used to indent levels in the JSON text.
166
+ attr_accessor :indent
167
+
168
+ # This string is used to insert a space between the tokens in a JSON
169
+ # string.
170
+ attr_accessor :space
171
+
172
+ # This string is used to insert a space before the ':' in JSON objects.
173
+ attr_accessor :space_before
174
+
175
+ # This string is put at the end of a line that holds a JSON object (or
176
+ # Hash).
177
+ attr_accessor :object_nl
178
+
179
+ # This string is put at the end of a line that holds a JSON array.
180
+ attr_accessor :array_nl
181
+
182
+ # This proc converts unsupported types into native JSON types.
183
+ attr_accessor :as_json
184
+
185
+ # This integer returns the maximum level of data structure nesting in
186
+ # the generated JSON, max_nesting = 0 if no maximum is checked.
187
+ attr_accessor :max_nesting
188
+
189
+ # If this attribute is set to true, forward slashes will be escaped in
190
+ # all json strings.
191
+ attr_accessor :script_safe
192
+
193
+ # If this attribute is set to true, attempting to serialize types not
194
+ # supported by the JSON spec will raise a JSON::GeneratorError
195
+ attr_accessor :strict
196
+
197
+ # :stopdoc:
198
+ attr_reader :buffer_initial_length
199
+
200
+ def buffer_initial_length=(length)
201
+ if length > 0
202
+ @buffer_initial_length = length
203
+ end
204
+ end
205
+ # :startdoc:
206
+
207
+ # This integer returns the current depth data structure nesting in the
208
+ # generated JSON.
209
+ attr_accessor :depth
210
+
211
+ def check_max_nesting # :nodoc:
212
+ return if @max_nesting.zero?
213
+ current_nesting = depth + 1
214
+ current_nesting > @max_nesting and
215
+ raise NestingError, "nesting of #{current_nesting} is too deep"
216
+ end
217
+
218
+ # Returns true, if circular data structures are checked,
219
+ # otherwise returns false.
220
+ def check_circular?
221
+ !@max_nesting.zero?
222
+ end
223
+
224
+ # Returns true if NaN, Infinity, and -Infinity should be considered as
225
+ # valid JSON and output.
226
+ def allow_nan?
227
+ @allow_nan
228
+ end
229
+
230
+ # Returns true, if only ASCII characters should be generated. Otherwise
231
+ # returns false.
232
+ def ascii_only?
233
+ @ascii_only
234
+ end
235
+
236
+ # Returns true, if forward slashes are escaped. Otherwise returns false.
237
+ def script_safe?
238
+ @script_safe
239
+ end
240
+
241
+ # Returns true, if strict mode is enabled. Otherwise returns false.
242
+ # Strict mode only allow serializing JSON native types: Hash, Array,
243
+ # String, Integer, Float, true, false and nil.
244
+ def strict?
245
+ @strict
246
+ end
247
+
248
+ # Configure this State instance with the Hash _opts_, and return
249
+ # itself.
250
+ def configure(opts)
251
+ if opts.respond_to?(:to_hash)
252
+ opts = opts.to_hash
253
+ elsif opts.respond_to?(:to_h)
254
+ opts = opts.to_h
255
+ else
256
+ raise TypeError, "can't convert #{opts.class} into Hash"
257
+ end
258
+ opts.each do |key, value|
259
+ instance_variable_set "@#{key}", value
260
+ end
261
+
262
+ # NOTE: If adding new instance variables here, check whether #generate should check them for #generate_json
263
+ @indent = opts[:indent] || '' if opts.key?(:indent)
264
+ @space = opts[:space] || '' if opts.key?(:space)
265
+ @space_before = opts[:space_before] || '' if opts.key?(:space_before)
266
+ @object_nl = opts[:object_nl] || '' if opts.key?(:object_nl)
267
+ @array_nl = opts[:array_nl] || '' if opts.key?(:array_nl)
268
+ @allow_nan = !!opts[:allow_nan] if opts.key?(:allow_nan)
269
+ @as_json = opts[:as_json].to_proc if opts[:as_json]
270
+ @ascii_only = opts[:ascii_only] if opts.key?(:ascii_only)
271
+ @depth = opts[:depth] || 0
272
+ @buffer_initial_length ||= opts[:buffer_initial_length]
273
+
274
+ @script_safe = if opts.key?(:script_safe)
275
+ !!opts[:script_safe]
276
+ elsif opts.key?(:escape_slash)
277
+ !!opts[:escape_slash]
278
+ else
279
+ false
280
+ end
281
+
282
+ if opts.key?(:allow_duplicate_key)
283
+ @allow_duplicate_key = !!opts[:allow_duplicate_key]
284
+ else
285
+ @allow_duplicate_key = nil # nil is deprecation
286
+ end
287
+
288
+ @strict = !!opts[:strict] if opts.key?(:strict)
289
+
290
+ if !opts.key?(:max_nesting) # defaults to 100
291
+ @max_nesting = 100
292
+ elsif opts[:max_nesting]
293
+ @max_nesting = opts[:max_nesting]
294
+ else
295
+ @max_nesting = 0
296
+ end
297
+ self
298
+ end
299
+ alias merge configure
300
+
301
+ def allow_duplicate_key? # :nodoc:
302
+ @allow_duplicate_key
303
+ end
304
+
305
+ # Returns the configuration instance variables as a hash, that can be
306
+ # passed to the configure method.
307
+ def to_h
308
+ result = {}
309
+ instance_variables.each do |iv|
310
+ iv = iv.to_s[1..-1]
311
+ result[iv.to_sym] = self[iv]
312
+ end
313
+
314
+ if result[:allow_duplicate_key].nil?
315
+ result.delete(:allow_duplicate_key)
316
+ end
317
+
318
+ result
319
+ end
320
+
321
+ alias to_hash to_h
322
+
323
+ # Generates a valid JSON document from object +obj+ and
324
+ # returns the result. If no valid JSON document can be
325
+ # created this method raises a
326
+ # GeneratorError exception.
327
+ def generate(obj, anIO = nil)
328
+ if @indent.empty? and @space.empty? and @space_before.empty? and @object_nl.empty? and @array_nl.empty? and
329
+ !@ascii_only and !@script_safe and @max_nesting == 0 and (!@strict || Symbol === obj)
330
+ result = generate_json(obj, ''.dup)
331
+ else
332
+ result = obj.to_json(self)
333
+ end
334
+ JSON::TruffleRuby::Generator.valid_utf8?(result) or raise GeneratorError.new(
335
+ "source sequence #{result.inspect} is illegal/malformed utf-8",
336
+ obj
337
+ )
338
+ if anIO
339
+ anIO.write(result)
340
+ anIO
341
+ else
342
+ result
343
+ end
344
+ end
345
+
346
+ def generate_new(obj, anIO = nil) # :nodoc:
347
+ dup.generate(obj, anIO)
348
+ end
349
+
350
+ # Handles @allow_nan, @buffer_initial_length, other ivars must be the default value (see above)
351
+ private def generate_json(obj, buf)
352
+ case obj
353
+ when Hash
354
+ buf << '{'
355
+ first = true
356
+ key_type = nil
357
+ obj.each_pair do |k,v|
358
+ if first
359
+ key_type = k.class
360
+ else
361
+ if key_type && !@allow_duplicate_key && key_type != k.class
362
+ key_type = nil # stop checking
363
+ JSON.send(:on_mixed_keys_hash, obj, !@allow_duplicate_key.nil?)
364
+ end
365
+ buf << ','
366
+ end
367
+
368
+ key_str = k.to_s
369
+ if key_str.class == String
370
+ fast_serialize_string(key_str, buf)
371
+ elsif key_str.is_a?(String)
372
+ generate_json(key_str, buf)
373
+ else
374
+ raise TypeError, "#{k.class}#to_s returns an instance of #{key_str.class}, expected a String"
375
+ end
376
+
377
+ buf << ':'
378
+ generate_json(v, buf)
379
+ first = false
380
+ end
381
+ buf << '}'
382
+ when Array
383
+ buf << '['
384
+ first = true
385
+ obj.each do |e|
386
+ buf << ',' unless first
387
+ generate_json(e, buf)
388
+ first = false
389
+ end
390
+ buf << ']'
391
+ when String
392
+ if obj.class == String
393
+ fast_serialize_string(obj, buf)
394
+ else
395
+ buf << obj.to_json(self)
396
+ end
397
+ when Integer
398
+ buf << obj.to_s
399
+ when Symbol
400
+ if @strict
401
+ fast_serialize_string(obj.name, buf)
402
+ else
403
+ buf << obj.to_json(self)
404
+ end
405
+ else
406
+ # Note: Float is handled this way since Float#to_s is slow anyway
407
+ buf << obj.to_json(self)
408
+ end
409
+ end
410
+
411
+ # Assumes !@ascii_only, !@script_safe
412
+ private def fast_serialize_string(string, buf) # :nodoc:
413
+ buf << '"'
414
+ unless string.encoding == ::Encoding::UTF_8
415
+ begin
416
+ string = string.encode(::Encoding::UTF_8)
417
+ rescue Encoding::UndefinedConversionError => error
418
+ raise GeneratorError.new(error.message, string)
419
+ end
420
+ end
421
+ raise GeneratorError.new("source sequence is illegal/malformed utf-8", string) unless string.valid_encoding?
422
+
423
+ if /["\\\x0-\x1f]/.match?(string)
424
+ buf << string.gsub(/["\\\x0-\x1f]/, MAP)
425
+ else
426
+ buf << string
427
+ end
428
+ buf << '"'
429
+ end
430
+
431
+ # Return the value returned by method +name+.
432
+ def [](name)
433
+ if respond_to?(name)
434
+ __send__(name)
435
+ else
436
+ instance_variable_get("@#{name}") if
437
+ instance_variables.include?("@#{name}".to_sym) # avoid warning
438
+ end
439
+ end
440
+
441
+ def []=(name, value)
442
+ if respond_to?(name_writer = "#{name}=")
443
+ __send__ name_writer, value
444
+ else
445
+ instance_variable_set "@#{name}", value
446
+ end
447
+ end
448
+ end
449
+
450
+ module GeneratorMethods
451
+ module Object
452
+ # Converts this object to a string (calling #to_s), converts
453
+ # it to a JSON string, and returns the result. This is a fallback, if no
454
+ # special method #to_json was defined for some object.
455
+ def to_json(state = nil, *)
456
+ state = State.from_state(state) if state
457
+ if state&.strict?
458
+ value = self
459
+ if state.strict? && !Generator.native_type?(value)
460
+ if state.as_json
461
+ value = state.as_json.call(value, false)
462
+ unless Generator.native_type?(value)
463
+ raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
464
+ end
465
+ value.to_json(state)
466
+ else
467
+ raise GeneratorError.new("#{value.class} not allowed in JSON", value)
468
+ end
469
+ end
470
+ else
471
+ to_s.to_json
472
+ end
473
+ end
474
+ end
475
+
476
+ module Hash
477
+ # Returns a JSON string containing a JSON object, that is unparsed from
478
+ # this Hash instance.
479
+ # _state_ is a JSON::State object, that can also be used to configure the
480
+ # produced JSON string output further.
481
+ # _depth_ is used to find out nesting depth, to indent accordingly.
482
+ def to_json(state = nil, *)
483
+ state = State.from_state(state)
484
+ state.check_max_nesting
485
+ json_transform(state)
486
+ end
487
+
488
+ private
489
+
490
+ def json_shift(state)
491
+ state.object_nl.empty? or return ''
492
+ state.indent * state.depth
493
+ end
494
+
495
+ def json_transform(state)
496
+ depth = state.depth += 1
497
+
498
+ if empty?
499
+ state.depth -= 1
500
+ return '{}'
501
+ end
502
+
503
+ delim = ",#{state.object_nl}"
504
+ result = +"{#{state.object_nl}"
505
+ first = true
506
+ key_type = nil
507
+ indent = !state.object_nl.empty?
508
+ each { |key, value|
509
+ if first
510
+ key_type = key.class
511
+ else
512
+ if key_type && !state.allow_duplicate_key? && key_type != key.class
513
+ key_type = nil # stop checking
514
+ JSON.send(:on_mixed_keys_hash, self, state.allow_duplicate_key? == false)
515
+ end
516
+ result << delim
517
+ end
518
+ result << state.indent * depth if indent
519
+
520
+ if state.strict? && !Generator.native_key?(key)
521
+ if state.as_json
522
+ key = state.as_json.call(key, true)
523
+ end
524
+
525
+ unless Generator.native_key?(key)
526
+ raise GeneratorError.new("#{key.class} not allowed as object key in JSON", value)
527
+ end
528
+ end
529
+
530
+ key_str = key.to_s
531
+ if key_str.is_a?(String)
532
+ key_json = key_str.to_json(state)
533
+ else
534
+ raise TypeError, "#{key.class}#to_s returns an instance of #{key_str.class}, expected a String"
535
+ end
536
+
537
+ result = +"#{result}#{key_json}#{state.space_before}:#{state.space}"
538
+ if state.strict? && !Generator.native_type?(value)
539
+ if state.as_json
540
+ value = state.as_json.call(value, false)
541
+ unless Generator.native_type?(value)
542
+ raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
543
+ end
544
+ result << value.to_json(state)
545
+ else
546
+ raise GeneratorError.new("#{value.class} not allowed in JSON", value)
547
+ end
548
+ elsif value.respond_to?(:to_json)
549
+ result << value.to_json(state)
550
+ else
551
+ result << %{"#{String(value)}"}
552
+ end
553
+ first = false
554
+ }
555
+ depth = state.depth -= 1
556
+ unless first
557
+ result << state.object_nl
558
+ result << state.indent * depth if indent
559
+ end
560
+ result << '}'
561
+ result
562
+ end
563
+ end
564
+
565
+ module Array
566
+ # Returns a JSON string containing a JSON array, that is unparsed from
567
+ # this Array instance.
568
+ # _state_ is a JSON::State object, that can also be used to configure the
569
+ # produced JSON string output further.
570
+ def to_json(state = nil, *)
571
+ state = State.from_state(state)
572
+ state.check_max_nesting
573
+ json_transform(state)
574
+ end
575
+
576
+ private
577
+
578
+ def json_transform(state)
579
+ depth = state.depth += 1
580
+
581
+ if empty?
582
+ state.depth -= 1
583
+ return '[]'
584
+ end
585
+
586
+ result = '['.dup
587
+ if state.array_nl.empty?
588
+ delim = ","
589
+ else
590
+ result << state.array_nl
591
+ delim = ",#{state.array_nl}"
592
+ end
593
+
594
+ first = true
595
+ indent = !state.array_nl.empty?
596
+ each { |value|
597
+ result << delim unless first
598
+ result << state.indent * depth if indent
599
+ if state.strict? && !Generator.native_type?(value)
600
+ if state.as_json
601
+ value = state.as_json.call(value, false)
602
+ unless Generator.native_type?(value)
603
+ raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
604
+ end
605
+ result << value.to_json(state)
606
+ else
607
+ raise GeneratorError.new("#{value.class} not allowed in JSON", value)
608
+ end
609
+ elsif value.respond_to?(:to_json)
610
+ result << value.to_json(state)
611
+ else
612
+ result << %{"#{String(value)}"}
613
+ end
614
+ first = false
615
+ }
616
+ depth = state.depth -= 1
617
+ result << state.array_nl
618
+ result << state.indent * depth if indent
619
+ result << ']'
620
+ end
621
+ end
622
+
623
+ module Integer
624
+ # Returns a JSON string representation for this Integer number.
625
+ def to_json(*) to_s end
626
+ end
627
+
628
+ module Float
629
+ # Returns a JSON string representation for this Float number.
630
+ def to_json(state = nil, *args)
631
+ state = State.from_state(state)
632
+ if infinite? || nan?
633
+ if state.allow_nan?
634
+ to_s
635
+ elsif state.strict? && state.as_json
636
+ casted_value = state.as_json.call(self, false)
637
+
638
+ if casted_value.equal?(self)
639
+ raise GeneratorError.new("#{self} not allowed in JSON", self)
640
+ end
641
+
642
+ state.check_max_nesting
643
+ state.depth += 1
644
+ result = casted_value.to_json(state, *args)
645
+ state.depth -= 1
646
+ result
647
+ else
648
+ raise GeneratorError.new("#{self} not allowed in JSON", self)
649
+ end
650
+ else
651
+ to_s
652
+ end
653
+ end
654
+ end
655
+
656
+ module Symbol
657
+ def to_json(state = nil, *args)
658
+ state = State.from_state(state)
659
+ if state.strict?
660
+ name.to_json(state, *args)
661
+ else
662
+ super
663
+ end
664
+ end
665
+ end
666
+
667
+ module String
668
+ # This string should be encoded with UTF-8 A call to this method
669
+ # returns a JSON string encoded with UTF16 big endian characters as
670
+ # \u????.
671
+ def to_json(state = nil, *args)
672
+ state = State.from_state(state)
673
+ if encoding == ::Encoding::UTF_8
674
+ unless valid_encoding?
675
+ raise GeneratorError.new("source sequence is illegal/malformed utf-8", self)
676
+ end
677
+ string = self
678
+ else
679
+ string = encode(::Encoding::UTF_8)
680
+ end
681
+ if state.ascii_only?
682
+ %("#{JSON::TruffleRuby::Generator.utf8_to_json_ascii(string, state.script_safe)}")
683
+ else
684
+ %("#{JSON::TruffleRuby::Generator.utf8_to_json(string, state.script_safe)}")
685
+ end
686
+ rescue Encoding::UndefinedConversionError => error
687
+ raise ::JSON::GeneratorError.new(error.message, self)
688
+ end
689
+ end
690
+
691
+ module TrueClass
692
+ # Returns a JSON string for true: 'true'.
693
+ def to_json(*) 'true' end
694
+ end
695
+
696
+ module FalseClass
697
+ # Returns a JSON string for false: 'false'.
698
+ def to_json(*) 'false' end
699
+ end
700
+
701
+ module NilClass
702
+ # Returns a JSON string for nil: 'null'.
703
+ def to_json(*) 'null' end
704
+ end
705
+ end
706
+ end
707
+ end
708
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JSON
4
+ VERSION = '2.15.1'
5
+ end