right_support 2.6.5 → 2.6.7
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.
- data/lib/right_support/data/hash_tools.rb +90 -0
- data/right_support.gemspec +3 -3
- metadata +5 -4
@@ -25,6 +25,8 @@ module RightSupport::Data
|
|
25
25
|
# various tools for manipulating hash-like classes.
|
26
26
|
module HashTools
|
27
27
|
|
28
|
+
HAS_JSON = require_succeeds?('json')
|
29
|
+
|
28
30
|
# Determines if given object is hashable (i.e. object responds to hash methods).
|
29
31
|
#
|
30
32
|
# === Parameters
|
@@ -257,5 +259,93 @@ module RightSupport::Data
|
|
257
259
|
target
|
258
260
|
end
|
259
261
|
|
262
|
+
class DeepSortedJsonState
|
263
|
+
|
264
|
+
# Initializer.
|
265
|
+
#
|
266
|
+
# === Parameters
|
267
|
+
# @param [TrueClass|FalseClass] pretty is true to invoke JSON::pretty_generate, false to call JSON::dump
|
268
|
+
def initialize(pretty)
|
269
|
+
# copy one of the JSON state prototypes in order to agree with recursive
|
270
|
+
# depth and other state variables.
|
271
|
+
@state = (pretty ? JSON::PRETTY_STATE_PROTOTYPE : JSON::FAST_STATE_PROTOTYPE).dup
|
272
|
+
|
273
|
+
# note that the native JSON extension *may* keep the following state
|
274
|
+
# strings as internal ruby strings in which case the state accessor (i.e.
|
275
|
+
# state.object_nl) returns a pointer to a char array instead of a String
|
276
|
+
# object. the trivial solution is to hardcode the 'pretty' strings here
|
277
|
+
# instead of trying to infer the proper string objects.
|
278
|
+
if pretty
|
279
|
+
@object_nl = "\n"
|
280
|
+
@indent = ' '
|
281
|
+
@space = ' '
|
282
|
+
else
|
283
|
+
@object_nl = ''
|
284
|
+
@indent = ''
|
285
|
+
@space = ''
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
# Generates a JSONified hash string where key/value pairs are sorted by
|
290
|
+
# the stringified key.
|
291
|
+
#
|
292
|
+
# Note that this algoritm is loosely based on the json_pure implementation
|
293
|
+
# for Hash.
|
294
|
+
#
|
295
|
+
# === Parameters
|
296
|
+
# @param [Hash] hash from which to generate JSON
|
297
|
+
#
|
298
|
+
# === Return
|
299
|
+
# @return [String] result as sorted JSONified hash
|
300
|
+
def generate(hash)
|
301
|
+
delim = ','
|
302
|
+
delim << @object_nl
|
303
|
+
result = '{'
|
304
|
+
result << @object_nl
|
305
|
+
depth = @state.depth += 1
|
306
|
+
first = true
|
307
|
+
|
308
|
+
sorted_pairs = hash.to_a.map { |key, value| [key.to_s, value] }.sort
|
309
|
+
sorted_pairs.each do |key, value|
|
310
|
+
result << delim unless first
|
311
|
+
result << @indent * depth
|
312
|
+
result << key.to_s.to_json(@state)
|
313
|
+
result << ':'
|
314
|
+
result << @space
|
315
|
+
if ::RightSupport::Data::HashTools.hashable?(value)
|
316
|
+
result << generate(value)
|
317
|
+
else
|
318
|
+
result << value.to_json(@state)
|
319
|
+
end
|
320
|
+
first = false
|
321
|
+
end
|
322
|
+
depth = @state.depth -= 1
|
323
|
+
result << @object_nl
|
324
|
+
result << @indent * depth
|
325
|
+
result << '}'
|
326
|
+
result
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
class NoJson < Exception; end
|
331
|
+
|
332
|
+
# Generates JSON from the given hash (of hashes) that is sorted by key at
|
333
|
+
# all levels. Does not handle case of hash to array of hashes, etc.
|
334
|
+
#
|
335
|
+
# === Parameters
|
336
|
+
# @param [Hash] hash from which to generate JSON
|
337
|
+
# @param [TrueClass|FalseClass] pretty is true to invoke JSON::pretty_generate, false to call JSON::dump
|
338
|
+
#
|
339
|
+
# === Return
|
340
|
+
# @return [String] result as a deep-sorted JSONized hash
|
341
|
+
def self.deep_sorted_json(hash, pretty=false)
|
342
|
+
if HAS_JSON
|
343
|
+
raise ArgumentError("'hash' was not hashable") unless hashable?(hash)
|
344
|
+
state = ::RightSupport::Data::HashTools::DeepSortedJsonState.new(pretty)
|
345
|
+
state.generate(hash)
|
346
|
+
else
|
347
|
+
raise NoJson, "JSON is unavailable"
|
348
|
+
end
|
349
|
+
end
|
260
350
|
end
|
261
351
|
end
|
data/right_support.gemspec
CHANGED
@@ -7,10 +7,10 @@ spec = Gem::Specification.new do |s|
|
|
7
7
|
s.required_ruby_version = Gem::Requirement.new(">= 1.8.7")
|
8
8
|
|
9
9
|
s.name = 'right_support'
|
10
|
-
s.version = '2.6.
|
11
|
-
s.date = '2012-
|
10
|
+
s.version = '2.6.7'
|
11
|
+
s.date = '2012-12-13'
|
12
12
|
|
13
|
-
s.authors = ['Tony Spataro', 'Sergey Sergyenko', 'Ryan Williamson', 'Lee Kirchhoff', 'Sergey Enin', 'Alexey Karpik']
|
13
|
+
s.authors = ['Tony Spataro', 'Sergey Sergyenko', 'Ryan Williamson', 'Lee Kirchhoff', 'Sergey Enin', 'Alexey Karpik', 'Scott Messier']
|
14
14
|
s.email = 'support@rightscale.com'
|
15
15
|
s.homepage= 'https://github.com/rightscale/right_support'
|
16
16
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: right_support
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 25
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 2
|
8
8
|
- 6
|
9
|
-
-
|
10
|
-
version: 2.6.
|
9
|
+
- 7
|
10
|
+
version: 2.6.7
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Tony Spataro
|
@@ -16,11 +16,12 @@ authors:
|
|
16
16
|
- Lee Kirchhoff
|
17
17
|
- Sergey Enin
|
18
18
|
- Alexey Karpik
|
19
|
+
- Scott Messier
|
19
20
|
autorequire:
|
20
21
|
bindir: bin
|
21
22
|
cert_chain: []
|
22
23
|
|
23
|
-
date: 2012-
|
24
|
+
date: 2012-12-13 00:00:00 -08:00
|
24
25
|
default_executable:
|
25
26
|
dependencies: []
|
26
27
|
|