Class: JSON::TruffleRuby::Generator::State

Inherits:
Object
  • Object
show all
Defined in:
lib/json/truffle_ruby/generator.rb

Overview

This class is used to create State instances, that are use to hold data while generating a JSON text from a Ruby data structure.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = nil) ⇒ State

Instantiates a new State object, configured by opts.

opts can have the following keys:

  • indent: a string used to indent levels (default: ''),
  • space: a string that is put after, a : or , delimiter (default: ''),
  • space_before: a string that is put before a : pair delimiter (default: ''),
  • object_nl: a string that is put at the end of a JSON object (default: ''),
  • array_nl: a string that is put at the end of a JSON array (default: ''),
  • script_safe: true if U+2028, U+2029 and forward slash (/) should be escaped as to make the JSON object safe to interpolate in a script tag (default: false).
  • check_circular: is deprecated now, use the :max_nesting option instead,
  • max_nesting: sets the maximum level of data structure nesting in the generated JSON, max_nesting = 0 if no maximum should be checked.
  • allow_nan: true if NaN, Infinity, and -Infinity should be generated, otherwise an exception is thrown, if these values are encountered. This options defaults to false.


155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/json/truffle_ruby/generator.rb', line 155

def initialize(opts = nil)
  @indent                = ''
  @space                 = ''
  @space_before          = ''
  @object_nl             = ''
  @array_nl              = ''
  @allow_nan             = false
  @ascii_only            = false
  @as_json               = false
  @depth                 = 0
  @buffer_initial_length = 1024
  @script_safe           = false
  @strict                = false
  @max_nesting           = 100
  @sort_keys             = false
  configure(opts) if opts
end

Instance Attribute Details

#array_nlObject

This string is put at the end of a line that holds a JSON array.



188
189
190
# File 'lib/json/truffle_ruby/generator.rb', line 188

def array_nl
  @array_nl
end

#as_jsonObject

This proc converts unsupported types into native JSON types.



191
192
193
# File 'lib/json/truffle_ruby/generator.rb', line 191

def as_json
  @as_json
end

#buffer_initial_lengthObject

:stopdoc:



233
234
235
# File 'lib/json/truffle_ruby/generator.rb', line 233

def buffer_initial_length
  @buffer_initial_length
end

#default_sort_keys_procObject

:nodoc:



114
115
116
# File 'lib/json/truffle_ruby/generator.rb', line 114

def default_sort_keys_proc
  @default_sort_keys_proc
end

#depthObject

This integer returns the current depth data structure nesting in the generated JSON.



244
245
246
# File 'lib/json/truffle_ruby/generator.rb', line 244

def depth
  @depth
end

#indentObject

This string is used to indent levels in the JSON text.



174
175
176
# File 'lib/json/truffle_ruby/generator.rb', line 174

def indent
  @indent
end

#max_nestingObject

This integer returns the maximum level of data structure nesting in the generated JSON, max_nesting = 0 if no maximum is checked.



195
196
197
# File 'lib/json/truffle_ruby/generator.rb', line 195

def max_nesting
  @max_nesting
end

#object_nlObject

This string is put at the end of a line that holds a JSON object (or Hash).



185
186
187
# File 'lib/json/truffle_ruby/generator.rb', line 185

def object_nl
  @object_nl
end

#script_safeObject

If this attribute is set to true, forward slashes will be escaped in all json strings.



199
200
201
# File 'lib/json/truffle_ruby/generator.rb', line 199

def script_safe
  @script_safe
end

#sort_keysObject

Controls key sorting in the generated JSON. If set to true, object keys are sorted by key lexicographically. If set to a Proc, it receives the entire Hash and must return a Hash with its pairs in the desired order.



209
210
211
# File 'lib/json/truffle_ruby/generator.rb', line 209

def sort_keys
  @sort_keys
end

#spaceObject

This string is used to insert a space between the tokens in a JSON string.



178
179
180
# File 'lib/json/truffle_ruby/generator.rb', line 178

def space
  @space
end

#space_beforeObject

This string is used to insert a space before the ':' in JSON objects.



181
182
183
# File 'lib/json/truffle_ruby/generator.rb', line 181

def space_before
  @space_before
end

#strictObject

If this attribute is set to true, attempting to serialize types not supported by the JSON spec will raise a JSON::GeneratorError



203
204
205
# File 'lib/json/truffle_ruby/generator.rb', line 203

def strict
  @strict
end

Class Method Details

.from_state(opts) ⇒ Object

Creates a State object from opts, which ought to be Hash to create a new State instance configured by opts, something else to create an unconfigured instance. If opts is a State object, it is just returned.



124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/json/truffle_ruby/generator.rb', line 124

def self.from_state(opts)
  if opts
    case
    when self === opts
      return opts
    when opts.respond_to?(:to_hash)
      return new(opts.to_hash)
    when opts.respond_to?(:to_h)
      return new(opts.to_h)
    end
  end
  new
end

.generate(obj, opts = nil, io = nil) ⇒ Object



116
117
118
# File 'lib/json/truffle_ruby/generator.rb', line 116

def self.generate(obj, opts = nil, io = nil)
  new(opts).generate(obj, io)
end

Instance Method Details

#[](name) ⇒ Object

Return the value returned by method name.



488
489
490
491
492
493
494
495
496
497
# File 'lib/json/truffle_ruby/generator.rb', line 488

def [](name)
  ::JSON.deprecation_warning("JSON::State#[] is deprecated and will be removed in json 3.0.0")

  if respond_to?(name)
    __send__(name)
  else
    instance_variable_get("@#{name}") if
      instance_variables.include?("@#{name}".to_sym) # avoid warning
  end
end

#[]=(name, value) ⇒ Object



499
500
501
502
503
504
505
506
507
# File 'lib/json/truffle_ruby/generator.rb', line 499

def []=(name, value)
  ::JSON.deprecation_warning("JSON::State#[]= is deprecated and will be removed in json 3.0.0")

  if respond_to?(name_writer = "#{name}=")
    __send__ name_writer, value
  else
    instance_variable_set "@#{name}", value
  end
end

#allow_duplicate_key?Boolean

:nodoc:

Returns:

  • (Boolean)


352
353
354
# File 'lib/json/truffle_ruby/generator.rb', line 352

def allow_duplicate_key? # :nodoc:
  @allow_duplicate_key
end

#allow_nan?Boolean

Returns true if NaN, Infinity, and -Infinity should be considered as valid JSON and output.

Returns:

  • (Boolean)


268
269
270
# File 'lib/json/truffle_ruby/generator.rb', line 268

def allow_nan?
  @allow_nan
end

#ascii_only?Boolean

Returns true, if only ASCII characters should be generated. Otherwise returns false.

Returns:

  • (Boolean)


274
275
276
# File 'lib/json/truffle_ruby/generator.rb', line 274

def ascii_only?
  @ascii_only
end

#check_circular?Boolean

Returns true, if circular data structures are checked, otherwise returns false.

Returns:

  • (Boolean)


262
263
264
# File 'lib/json/truffle_ruby/generator.rb', line 262

def check_circular?
  !@max_nesting.zero?
end

#check_max_nestingObject

:nodoc:



253
254
255
256
257
258
# File 'lib/json/truffle_ruby/generator.rb', line 253

def check_max_nesting # :nodoc:
  return if @max_nesting.zero?
  current_nesting = depth + 1
  current_nesting > @max_nesting and
    raise NestingError, "nesting of #{current_nesting} is too deep. Did you try to serialize objects with circular references?"
end

#configure(opts) ⇒ Object Also known as: merge

Configure this State instance with the Hash opts, and return itself.



292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
# File 'lib/json/truffle_ruby/generator.rb', line 292

def configure(opts)
  if opts.respond_to?(:to_hash)
    opts = opts.to_hash
  elsif opts.respond_to?(:to_h)
    opts = opts.to_h
  else
    raise TypeError, "can't convert #{opts.class} into Hash"
  end

  if opts[:depth]&.negative?
    raise ArgumentError, "depth must be >= 0 (got #{opts[:depth]})"
  end

  opts.each do |key, value|
    instance_variable_set "@#{key}", value
  end

  # NOTE: If adding new instance variables here, check whether #generate should check them for #generate_json
  @indent                = opts[:indent]        || '' if opts.key?(:indent)
  @space                 = opts[:space]         || '' if opts.key?(:space)
  @space_before          = opts[:space_before]  || '' if opts.key?(:space_before)
  @object_nl             = opts[:object_nl]     || '' if opts.key?(:object_nl)
  @array_nl              = opts[:array_nl]      || '' if opts.key?(:array_nl)
  @allow_nan             = !!opts[:allow_nan]         if opts.key?(:allow_nan)
  @as_json               = opts[:as_json].to_proc     if opts[:as_json]
  @ascii_only            = opts[:ascii_only]          if opts.key?(:ascii_only)
  self.sort_keys         = opts[:sort_keys]           if opts.key?(:sort_keys)
  @depth                 = opts[:depth] || 0
  @buffer_initial_length ||= opts[:buffer_initial_length]

  @script_safe = if opts.key?(:script_safe)
    !!opts[:script_safe]
  elsif opts.key?(:escape_slash)
    !!opts[:escape_slash]
  else
    false
  end

  if opts.key?(:allow_duplicate_key)
    @allow_duplicate_key = !!opts[:allow_duplicate_key]
  else
    @allow_duplicate_key = nil # nil is deprecation
  end

  @strict                = !!opts[:strict] if opts.key?(:strict)

  if !opts.key?(:max_nesting) # defaults to 100
    @max_nesting = 100
  elsif opts[:max_nesting]
    unless opts[:max_nesting].is_a?(Integer)
      raise TypeError, ":max_nesting must be an Integer, got: #{opts[:max_nesting].class}"
    end
    @max_nesting = opts[:max_nesting]
  else
    @max_nesting = 0
  end
  self
end

#generate(obj, anIO = nil) ⇒ Object

Generates a valid JSON document from object obj and returns the result. If no valid JSON document can be created this method raises a GeneratorError exception.



378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
# File 'lib/json/truffle_ruby/generator.rb', line 378

def generate(obj, anIO = nil)
  return dup.generate(obj, anIO) if frozen?

  depth = @depth
  if @indent.empty? and @space.empty? and @space_before.empty? and @object_nl.empty? and @array_nl.empty? and
      !@ascii_only and !@script_safe and @max_nesting == 0 and (!@strict || Symbol === obj) and !@sort_keys
    result = generate_json(obj, ''.dup)
  else
    if @sort_keys
      obj = @sort_keys.call(obj)
    end

    result = obj.to_json(self)
  end
  JSON::TruffleRuby::Generator.valid_utf8?(result) or raise GeneratorError.new(
    "source sequence #{result.inspect} is illegal/malformed utf-8",
    obj
  )
  if anIO
    anIO.write(result)
    anIO
  else
    result
  end
ensure
  @depth = depth unless frozen?
end

#script_safe?Boolean

Returns true, if forward slashes are escaped. Otherwise returns false.

Returns:

  • (Boolean)


279
280
281
# File 'lib/json/truffle_ruby/generator.rb', line 279

def script_safe?
  @script_safe
end

#strict?Boolean

Returns true, if strict mode is enabled. Otherwise returns false. Strict mode only allow serializing JSON native types: Hash, Array, String, Integer, Float, true, false and nil.

Returns:

  • (Boolean)


286
287
288
# File 'lib/json/truffle_ruby/generator.rb', line 286

def strict?
  @strict
end

#to_hObject Also known as: to_hash

Returns the configuration instance variables as a hash, that can be passed to the configure method.



358
359
360
361
362
363
364
365
366
367
368
369
370
# File 'lib/json/truffle_ruby/generator.rb', line 358

def to_h
  result = {}
  instance_variables.each do |iv|
    key = iv.to_s[1..-1]
    result[key.to_sym] = instance_variable_get(iv)
  end

  if result[:allow_duplicate_key].nil?
    result.delete(:allow_duplicate_key)
  end

  result
end