Class: RightSupport::Data::HashTools::DeepSortedJsonState

Inherits:
Object
  • Object
show all
Defined in:
lib/right_support/data/hash_tools.rb

Instance Method Summary collapse

Constructor Details

#initialize(pretty) ⇒ DeepSortedJsonState

Initializer.

Parameters



268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
# File 'lib/right_support/data/hash_tools.rb', line 268

def initialize(pretty)
  # copy one of the JSON state prototypes in order to agree with recursive
  # depth and other state variables.
  @state = (pretty ? JSON::PRETTY_STATE_PROTOTYPE : JSON::FAST_STATE_PROTOTYPE).dup

  # note that the native JSON extension *may* keep the following state
  # strings as internal ruby strings in which case the state accessor (i.e.
  # state.object_nl) returns a pointer to a char array instead of a String
  # object. the trivial solution is to hardcode the 'pretty' strings here
  # instead of trying to infer the proper string objects.
  if pretty
    @object_nl = "\n"
    @indent    = '  '
    @space     = ' '
  else
    @object_nl = ''
    @indent    = ''
    @space     = ''
  end
end

Instance Method Details

#generate(hash) ⇒ String

Generates a JSONified hash string where key/value pairs are sorted by the stringified key.

Note that this algoritm is loosely based on the json_pure implementation for Hash.

Parameters

Return



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
# File 'lib/right_support/data/hash_tools.rb', line 300

def generate(hash)
  delim = ','
  delim << @object_nl
  result = '{'
  result << @object_nl
  depth = @state.depth += 1
  first = true

  sorted_pairs = hash.to_a.map { |key, value| [key.to_s, value] }.sort
  sorted_pairs.each do |key, value|
    result << delim unless first
    result << @indent * depth
    result << key.to_s.to_json(@state)
    result << ':'
    result << @space
    if ::RightSupport::Data::HashTools.hashable?(value)
      result << generate(value)
    else
      result << value.to_json(@state)
    end
    first = false
  end
  depth = @state.depth -= 1
  result << @object_nl
  result << @indent * depth
  result << '}'
  result
end