angry_mob 0.1.0

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.
Files changed (125) hide show
  1. data/LICENSE +21 -0
  2. data/README.md +123 -0
  3. data/bin/mob +139 -0
  4. data/lib/angry_mob.rb +28 -0
  5. data/lib/angry_mob/act.rb +111 -0
  6. data/lib/angry_mob/act/scheduler.rb +143 -0
  7. data/lib/angry_mob/action.rb +11 -0
  8. data/lib/angry_mob/builder.rb +115 -0
  9. data/lib/angry_mob/extend.rb +10 -0
  10. data/lib/angry_mob/extend/array.rb +30 -0
  11. data/lib/angry_mob/extend/blank.rb +108 -0
  12. data/lib/angry_mob/extend/blankslate.rb +109 -0
  13. data/lib/angry_mob/extend/dictionary.rb +140 -0
  14. data/lib/angry_mob/extend/hash.rb +67 -0
  15. data/lib/angry_mob/extend/object.rb +21 -0
  16. data/lib/angry_mob/extend/pathname.rb +23 -0
  17. data/lib/angry_mob/extend/string.rb +8 -0
  18. data/lib/angry_mob/log.rb +28 -0
  19. data/lib/angry_mob/mob.rb +77 -0
  20. data/lib/angry_mob/mob_loader.rb +115 -0
  21. data/lib/angry_mob/node.rb +44 -0
  22. data/lib/angry_mob/notifier.rb +76 -0
  23. data/lib/angry_mob/target.rb +257 -0
  24. data/lib/angry_mob/target/arguments.rb +71 -0
  25. data/lib/angry_mob/target/call.rb +57 -0
  26. data/lib/angry_mob/target/default_resource_locator.rb +11 -0
  27. data/lib/angry_mob/target/defaults.rb +23 -0
  28. data/lib/angry_mob/target/mother.rb +66 -0
  29. data/lib/angry_mob/target/notify.rb +57 -0
  30. data/lib/angry_mob/target/tracking.rb +96 -0
  31. data/lib/angry_mob/ui.rb +247 -0
  32. data/lib/angry_mob/util.rb +11 -0
  33. data/lib/angry_mob/vendored.rb +8 -0
  34. data/lib/angry_mob/version.rb +3 -0
  35. data/vendor/angry_hash/Rakefile +17 -0
  36. data/vendor/angry_hash/VERSION +1 -0
  37. data/vendor/angry_hash/angry_hash.gemspec +47 -0
  38. data/vendor/angry_hash/examples/accessors_eg.rb +46 -0
  39. data/vendor/angry_hash/examples/creation_eg.rb +43 -0
  40. data/vendor/angry_hash/examples/dsl.eg.rb +18 -0
  41. data/vendor/angry_hash/examples/dup_eg.rb +86 -0
  42. data/vendor/angry_hash/examples/eg_helper.rb +24 -0
  43. data/vendor/angry_hash/examples/merge_eg.rb +135 -0
  44. data/vendor/angry_hash/lib/angry_hash.rb +215 -0
  45. data/vendor/angry_hash/lib/angry_hash/dsl.rb +44 -0
  46. data/vendor/angry_hash/lib/angry_hash/extension_tracking.rb +12 -0
  47. data/vendor/angry_hash/lib/angry_hash/merge_string.rb +58 -0
  48. data/vendor/json/COPYING +58 -0
  49. data/vendor/json/GPL +340 -0
  50. data/vendor/json/README +360 -0
  51. data/vendor/json/lib/json/common.rb +371 -0
  52. data/vendor/json/lib/json/pure.rb +77 -0
  53. data/vendor/json/lib/json/pure/generator.rb +443 -0
  54. data/vendor/json/lib/json/pure/parser.rb +303 -0
  55. data/vendor/json/lib/json/version.rb +8 -0
  56. data/vendor/thor/CHANGELOG.rdoc +89 -0
  57. data/vendor/thor/LICENSE +20 -0
  58. data/vendor/thor/README.rdoc +297 -0
  59. data/vendor/thor/Thorfile +69 -0
  60. data/vendor/thor/bin/rake2thor +86 -0
  61. data/vendor/thor/bin/thor +6 -0
  62. data/vendor/thor/lib/thor.rb +244 -0
  63. data/vendor/thor/lib/thor/actions.rb +275 -0
  64. data/vendor/thor/lib/thor/actions/create_file.rb +103 -0
  65. data/vendor/thor/lib/thor/actions/directory.rb +91 -0
  66. data/vendor/thor/lib/thor/actions/empty_directory.rb +134 -0
  67. data/vendor/thor/lib/thor/actions/file_manipulation.rb +223 -0
  68. data/vendor/thor/lib/thor/actions/inject_into_file.rb +104 -0
  69. data/vendor/thor/lib/thor/base.rb +540 -0
  70. data/vendor/thor/lib/thor/core_ext/file_binary_read.rb +9 -0
  71. data/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +75 -0
  72. data/vendor/thor/lib/thor/core_ext/ordered_hash.rb +100 -0
  73. data/vendor/thor/lib/thor/error.rb +30 -0
  74. data/vendor/thor/lib/thor/group.rb +271 -0
  75. data/vendor/thor/lib/thor/invocation.rb +180 -0
  76. data/vendor/thor/lib/thor/parser.rb +4 -0
  77. data/vendor/thor/lib/thor/parser/argument.rb +67 -0
  78. data/vendor/thor/lib/thor/parser/arguments.rb +150 -0
  79. data/vendor/thor/lib/thor/parser/option.rb +128 -0
  80. data/vendor/thor/lib/thor/parser/options.rb +169 -0
  81. data/vendor/thor/lib/thor/rake_compat.rb +66 -0
  82. data/vendor/thor/lib/thor/runner.rb +314 -0
  83. data/vendor/thor/lib/thor/shell.rb +83 -0
  84. data/vendor/thor/lib/thor/shell/basic.rb +239 -0
  85. data/vendor/thor/lib/thor/shell/color.rb +108 -0
  86. data/vendor/thor/lib/thor/task.rb +102 -0
  87. data/vendor/thor/lib/thor/util.rb +224 -0
  88. data/vendor/thor/lib/thor/version.rb +3 -0
  89. data/vendor/thor/spec/actions/create_file_spec.rb +170 -0
  90. data/vendor/thor/spec/actions/directory_spec.rb +131 -0
  91. data/vendor/thor/spec/actions/empty_directory_spec.rb +91 -0
  92. data/vendor/thor/spec/actions/file_manipulation_spec.rb +271 -0
  93. data/vendor/thor/spec/actions/inject_into_file_spec.rb +135 -0
  94. data/vendor/thor/spec/actions_spec.rb +292 -0
  95. data/vendor/thor/spec/base_spec.rb +263 -0
  96. data/vendor/thor/spec/core_ext/hash_with_indifferent_access_spec.rb +43 -0
  97. data/vendor/thor/spec/core_ext/ordered_hash_spec.rb +115 -0
  98. data/vendor/thor/spec/fixtures/application.rb +2 -0
  99. data/vendor/thor/spec/fixtures/bundle/execute.rb +6 -0
  100. data/vendor/thor/spec/fixtures/bundle/main.thor +1 -0
  101. data/vendor/thor/spec/fixtures/doc/%file_name%.rb.tt +1 -0
  102. data/vendor/thor/spec/fixtures/doc/README +3 -0
  103. data/vendor/thor/spec/fixtures/doc/config.rb +1 -0
  104. data/vendor/thor/spec/fixtures/group.thor +90 -0
  105. data/vendor/thor/spec/fixtures/invoke.thor +112 -0
  106. data/vendor/thor/spec/fixtures/script.thor +145 -0
  107. data/vendor/thor/spec/fixtures/task.thor +10 -0
  108. data/vendor/thor/spec/group_spec.rb +171 -0
  109. data/vendor/thor/spec/invocation_spec.rb +107 -0
  110. data/vendor/thor/spec/parser/argument_spec.rb +47 -0
  111. data/vendor/thor/spec/parser/arguments_spec.rb +64 -0
  112. data/vendor/thor/spec/parser/option_spec.rb +202 -0
  113. data/vendor/thor/spec/parser/options_spec.rb +292 -0
  114. data/vendor/thor/spec/rake_compat_spec.rb +68 -0
  115. data/vendor/thor/spec/runner_spec.rb +210 -0
  116. data/vendor/thor/spec/shell/basic_spec.rb +205 -0
  117. data/vendor/thor/spec/shell/color_spec.rb +41 -0
  118. data/vendor/thor/spec/shell_spec.rb +34 -0
  119. data/vendor/thor/spec/spec.opts +1 -0
  120. data/vendor/thor/spec/spec_helper.rb +54 -0
  121. data/vendor/thor/spec/task_spec.rb +69 -0
  122. data/vendor/thor/spec/thor_spec.rb +237 -0
  123. data/vendor/thor/spec/util_spec.rb +163 -0
  124. data/vendor/thor/thor.gemspec +120 -0
  125. metadata +199 -0
@@ -0,0 +1,77 @@
1
+ require 'json/common'
2
+ require 'json/pure/parser'
3
+ require 'json/pure/generator'
4
+
5
+ module JSON
6
+ begin
7
+ require 'iconv'
8
+ # An iconv instance to convert from UTF8 to UTF16 Big Endian.
9
+ UTF16toUTF8 = Iconv.new('utf-8', 'utf-16be') # :nodoc:
10
+ # An iconv instance to convert from UTF16 Big Endian to UTF8.
11
+ UTF8toUTF16 = Iconv.new('utf-16be', 'utf-8') # :nodoc:
12
+ UTF8toUTF16.iconv('no bom')
13
+ rescue LoadError
14
+ raise MissingUnicodeSupport,
15
+ "iconv couldn't be loaded, which is required for UTF-8/UTF-16 conversions"
16
+ rescue Errno::EINVAL, Iconv::InvalidEncoding
17
+ # Iconv doesn't support big endian utf-16. Let's try to hack this manually
18
+ # into the converters.
19
+ begin
20
+ old_verbose, $VERBSOSE = $VERBOSE, nil
21
+ # An iconv instance to convert from UTF8 to UTF16 Big Endian.
22
+ UTF16toUTF8 = Iconv.new('utf-8', 'utf-16') # :nodoc:
23
+ # An iconv instance to convert from UTF16 Big Endian to UTF8.
24
+ UTF8toUTF16 = Iconv.new('utf-16', 'utf-8') # :nodoc:
25
+ UTF8toUTF16.iconv('no bom')
26
+ if UTF8toUTF16.iconv("\xe2\x82\xac") == "\xac\x20"
27
+ swapper = Class.new do
28
+ def initialize(iconv) # :nodoc:
29
+ @iconv = iconv
30
+ end
31
+
32
+ def iconv(string) # :nodoc:
33
+ result = @iconv.iconv(string)
34
+ JSON.swap!(result)
35
+ end
36
+ end
37
+ UTF8toUTF16 = swapper.new(UTF8toUTF16) # :nodoc:
38
+ end
39
+ if UTF16toUTF8.iconv("\xac\x20") == "\xe2\x82\xac"
40
+ swapper = Class.new do
41
+ def initialize(iconv) # :nodoc:
42
+ @iconv = iconv
43
+ end
44
+
45
+ def iconv(string) # :nodoc:
46
+ string = JSON.swap!(string.dup)
47
+ @iconv.iconv(string)
48
+ end
49
+ end
50
+ UTF16toUTF8 = swapper.new(UTF16toUTF8) # :nodoc:
51
+ end
52
+ rescue Errno::EINVAL, Iconv::InvalidEncoding
53
+ raise MissingUnicodeSupport, "iconv doesn't seem to support UTF-8/UTF-16 conversions"
54
+ ensure
55
+ $VERBOSE = old_verbose
56
+ end
57
+ end
58
+
59
+ # Swap consecutive bytes of _string_ in place.
60
+ def self.swap!(string) # :nodoc:
61
+ 0.upto(string.size / 2) do |i|
62
+ break unless string[2 * i + 1]
63
+ string[2 * i], string[2 * i + 1] = string[2 * i + 1], string[2 * i]
64
+ end
65
+ string
66
+ end
67
+
68
+ # This module holds all the modules/classes that implement JSON's
69
+ # functionality in pure ruby.
70
+ module Pure
71
+ $DEBUG and warn "Using pure library for JSON."
72
+ JSON.parser = Parser
73
+ JSON.generator = Generator
74
+ end
75
+
76
+ JSON_LOADED = true
77
+ end
@@ -0,0 +1,443 @@
1
+ module JSON
2
+ MAP = {
3
+ "\x0" => '\u0000',
4
+ "\x1" => '\u0001',
5
+ "\x2" => '\u0002',
6
+ "\x3" => '\u0003',
7
+ "\x4" => '\u0004',
8
+ "\x5" => '\u0005',
9
+ "\x6" => '\u0006',
10
+ "\x7" => '\u0007',
11
+ "\b" => '\b',
12
+ "\t" => '\t',
13
+ "\n" => '\n',
14
+ "\xb" => '\u000b',
15
+ "\f" => '\f',
16
+ "\r" => '\r',
17
+ "\xe" => '\u000e',
18
+ "\xf" => '\u000f',
19
+ "\x10" => '\u0010',
20
+ "\x11" => '\u0011',
21
+ "\x12" => '\u0012',
22
+ "\x13" => '\u0013',
23
+ "\x14" => '\u0014',
24
+ "\x15" => '\u0015',
25
+ "\x16" => '\u0016',
26
+ "\x17" => '\u0017',
27
+ "\x18" => '\u0018',
28
+ "\x19" => '\u0019',
29
+ "\x1a" => '\u001a',
30
+ "\x1b" => '\u001b',
31
+ "\x1c" => '\u001c',
32
+ "\x1d" => '\u001d',
33
+ "\x1e" => '\u001e',
34
+ "\x1f" => '\u001f',
35
+ '"' => '\"',
36
+ '\\' => '\\\\',
37
+ } # :nodoc:
38
+
39
+ # Convert a UTF8 encoded Ruby string _string_ to a JSON string, encoded with
40
+ # UTF16 big endian characters as \u????, and return it.
41
+ if defined?(::Encoding)
42
+ def utf8_to_json(string) # :nodoc:
43
+ string = string.dup
44
+ string << '' # XXX workaround: avoid buffer sharing
45
+ string.force_encoding(::Encoding::ASCII_8BIT)
46
+ string.gsub!(/["\\\x0-\x1f]/) { MAP[$&] }
47
+ string.gsub!(/(
48
+ (?:
49
+ [\xc2-\xdf][\x80-\xbf] |
50
+ [\xe0-\xef][\x80-\xbf]{2} |
51
+ [\xf0-\xf4][\x80-\xbf]{3}
52
+ )+ |
53
+ [\x80-\xc1\xf5-\xff] # invalid
54
+ )/nx) { |c|
55
+ c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
56
+ s = JSON::UTF8toUTF16.iconv(c).unpack('H*')[0]
57
+ s.gsub!(/.{4}/n, '\\\\u\&')
58
+ }
59
+ string.force_encoding(::Encoding::UTF_8)
60
+ string
61
+ rescue Iconv::Failure => e
62
+ raise GeneratorError, "Caught #{e.class}: #{e}"
63
+ end
64
+ else
65
+ def utf8_to_json(string) # :nodoc:
66
+ string = string.gsub(/["\\\x0-\x1f]/) { MAP[$&] }
67
+ string.gsub!(/(
68
+ (?:
69
+ [\xc2-\xdf][\x80-\xbf] |
70
+ [\xe0-\xef][\x80-\xbf]{2} |
71
+ [\xf0-\xf4][\x80-\xbf]{3}
72
+ )+ |
73
+ [\x80-\xc1\xf5-\xff] # invalid
74
+ )/nx) { |c|
75
+ c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
76
+ s = JSON::UTF8toUTF16.iconv(c).unpack('H*')[0]
77
+ s.gsub!(/.{4}/n, '\\\\u\&')
78
+ }
79
+ string
80
+ rescue Iconv::Failure => e
81
+ raise GeneratorError, "Caught #{e.class}: #{e}"
82
+ end
83
+ end
84
+ module_function :utf8_to_json
85
+
86
+ module Pure
87
+ module Generator
88
+ # This class is used to create State instances, that are use to hold data
89
+ # while generating a JSON text from a a Ruby data structure.
90
+ class State
91
+ # Creates a State object from _opts_, which ought to be Hash to create
92
+ # a new State instance configured by _opts_, something else to create
93
+ # an unconfigured instance. If _opts_ is a State object, it is just
94
+ # returned.
95
+ def self.from_state(opts)
96
+ case opts
97
+ when self
98
+ opts
99
+ when Hash
100
+ new(opts)
101
+ else
102
+ new
103
+ end
104
+ end
105
+
106
+ # Instantiates a new State object, configured by _opts_.
107
+ #
108
+ # _opts_ can have the following keys:
109
+ #
110
+ # * *indent*: a string used to indent levels (default: ''),
111
+ # * *space*: a string that is put after, a : or , delimiter (default: ''),
112
+ # * *space_before*: a string that is put before a : pair delimiter (default: ''),
113
+ # * *object_nl*: a string that is put at the end of a JSON object (default: ''),
114
+ # * *array_nl*: a string that is put at the end of a JSON array (default: ''),
115
+ # * *check_circular*: true if checking for circular data structures
116
+ # should be done (the default), false otherwise.
117
+ # * *check_circular*: true if checking for circular data structures
118
+ # should be done, false (the default) otherwise.
119
+ # * *allow_nan*: true if NaN, Infinity, and -Infinity should be
120
+ # generated, otherwise an exception is thrown, if these values are
121
+ # encountered. This options defaults to false.
122
+ def initialize(opts = {})
123
+ @seen = {}
124
+ @indent = ''
125
+ @space = ''
126
+ @space_before = ''
127
+ @object_nl = ''
128
+ @array_nl = ''
129
+ @check_circular = true
130
+ @allow_nan = false
131
+ configure opts
132
+ end
133
+
134
+ # This string is used to indent levels in the JSON text.
135
+ attr_accessor :indent
136
+
137
+ # This string is used to insert a space between the tokens in a JSON
138
+ # string.
139
+ attr_accessor :space
140
+
141
+ # This string is used to insert a space before the ':' in JSON objects.
142
+ attr_accessor :space_before
143
+
144
+ # This string is put at the end of a line that holds a JSON object (or
145
+ # Hash).
146
+ attr_accessor :object_nl
147
+
148
+ # This string is put at the end of a line that holds a JSON array.
149
+ attr_accessor :array_nl
150
+
151
+ # This integer returns the maximum level of data structure nesting in
152
+ # the generated JSON, max_nesting = 0 if no maximum is checked.
153
+ attr_accessor :max_nesting
154
+
155
+ def check_max_nesting(depth) # :nodoc:
156
+ return if @max_nesting.zero?
157
+ current_nesting = depth + 1
158
+ current_nesting > @max_nesting and
159
+ raise NestingError, "nesting of #{current_nesting} is too deep"
160
+ end
161
+
162
+ # Returns true, if circular data structures should be checked,
163
+ # otherwise returns false.
164
+ def check_circular?
165
+ @check_circular
166
+ end
167
+
168
+ # Returns true if NaN, Infinity, and -Infinity should be considered as
169
+ # valid JSON and output.
170
+ def allow_nan?
171
+ @allow_nan
172
+ end
173
+
174
+ # Returns _true_, if _object_ was already seen during this generating
175
+ # run.
176
+ def seen?(object)
177
+ @seen.key?(object.__id__)
178
+ end
179
+
180
+ # Remember _object_, to find out if it was already encountered (if a
181
+ # cyclic data structure is if a cyclic data structure is rendered).
182
+ def remember(object)
183
+ @seen[object.__id__] = true
184
+ end
185
+
186
+ # Forget _object_ for this generating run.
187
+ def forget(object)
188
+ @seen.delete object.__id__
189
+ end
190
+
191
+ # Configure this State instance with the Hash _opts_, and return
192
+ # itself.
193
+ def configure(opts)
194
+ @indent = opts[:indent] if opts.key?(:indent)
195
+ @space = opts[:space] if opts.key?(:space)
196
+ @space_before = opts[:space_before] if opts.key?(:space_before)
197
+ @object_nl = opts[:object_nl] if opts.key?(:object_nl)
198
+ @array_nl = opts[:array_nl] if opts.key?(:array_nl)
199
+ @check_circular = !!opts[:check_circular] if opts.key?(:check_circular)
200
+ @allow_nan = !!opts[:allow_nan] if opts.key?(:allow_nan)
201
+ if !opts.key?(:max_nesting) # defaults to 19
202
+ @max_nesting = 19
203
+ elsif opts[:max_nesting]
204
+ @max_nesting = opts[:max_nesting]
205
+ else
206
+ @max_nesting = 0
207
+ end
208
+ self
209
+ end
210
+
211
+ # Returns the configuration instance variables as a hash, that can be
212
+ # passed to the configure method.
213
+ def to_h
214
+ result = {}
215
+ for iv in %w[indent space space_before object_nl array_nl check_circular allow_nan max_nesting]
216
+ result[iv.intern] = instance_variable_get("@#{iv}")
217
+ end
218
+ result
219
+ end
220
+ end
221
+
222
+ module GeneratorMethods
223
+ module Object
224
+ # Converts this object to a string (calling #to_s), converts
225
+ # it to a JSON string, and returns the result. This is a fallback, if no
226
+ # special method #to_json was defined for some object.
227
+ def to_json(*) to_s.to_json end
228
+ end
229
+
230
+ module Hash
231
+ # Returns a JSON string containing a JSON object, that is unparsed from
232
+ # this Hash instance.
233
+ # _state_ is a JSON::State object, that can also be used to configure the
234
+ # produced JSON string output further.
235
+ # _depth_ is used to find out nesting depth, to indent accordingly.
236
+ def to_json(state = nil, depth = 0, *)
237
+ if state
238
+ state = JSON.state.from_state(state)
239
+ state.check_max_nesting(depth)
240
+ json_check_circular(state) { json_transform(state, depth) }
241
+ else
242
+ json_transform(state, depth)
243
+ end
244
+ end
245
+
246
+ private
247
+
248
+ def json_check_circular(state)
249
+ if state and state.check_circular?
250
+ state.seen?(self) and raise JSON::CircularDatastructure,
251
+ "circular data structures not supported!"
252
+ state.remember self
253
+ end
254
+ yield
255
+ ensure
256
+ state and state.forget self
257
+ end
258
+
259
+ def json_shift(state, depth)
260
+ state and not state.object_nl.empty? or return ''
261
+ state.indent * depth
262
+ end
263
+
264
+ def json_transform(state, depth)
265
+ delim = ','
266
+ if state
267
+ delim << state.object_nl
268
+ result = '{'
269
+ result << state.object_nl
270
+ result << map { |key,value|
271
+ s = json_shift(state, depth + 1)
272
+ s << key.to_s.to_json(state, depth + 1)
273
+ s << state.space_before
274
+ s << ':'
275
+ s << state.space
276
+ s << value.to_json(state, depth + 1)
277
+ }.join(delim)
278
+ result << state.object_nl
279
+ result << json_shift(state, depth)
280
+ result << '}'
281
+ else
282
+ result = '{'
283
+ result << map { |key,value|
284
+ key.to_s.to_json << ':' << value.to_json
285
+ }.join(delim)
286
+ result << '}'
287
+ end
288
+ result
289
+ end
290
+ end
291
+
292
+ module Array
293
+ # Returns a JSON string containing a JSON array, that is unparsed from
294
+ # this Array instance.
295
+ # _state_ is a JSON::State object, that can also be used to configure the
296
+ # produced JSON string output further.
297
+ # _depth_ is used to find out nesting depth, to indent accordingly.
298
+ def to_json(state = nil, depth = 0, *)
299
+ if state
300
+ state = JSON.state.from_state(state)
301
+ state.check_max_nesting(depth)
302
+ json_check_circular(state) { json_transform(state, depth) }
303
+ else
304
+ json_transform(state, depth)
305
+ end
306
+ end
307
+
308
+ private
309
+
310
+ def json_check_circular(state)
311
+ if state and state.check_circular?
312
+ state.seen?(self) and raise JSON::CircularDatastructure,
313
+ "circular data structures not supported!"
314
+ state.remember self
315
+ end
316
+ yield
317
+ ensure
318
+ state and state.forget self
319
+ end
320
+
321
+ def json_shift(state, depth)
322
+ state and not state.array_nl.empty? or return ''
323
+ state.indent * depth
324
+ end
325
+
326
+ def json_transform(state, depth)
327
+ delim = ','
328
+ if state
329
+ delim << state.array_nl
330
+ result = '['
331
+ result << state.array_nl
332
+ result << map { |value|
333
+ json_shift(state, depth + 1) << value.to_json(state, depth + 1)
334
+ }.join(delim)
335
+ result << state.array_nl
336
+ result << json_shift(state, depth)
337
+ result << ']'
338
+ else
339
+ '[' << map { |value| value.to_json }.join(delim) << ']'
340
+ end
341
+ end
342
+ end
343
+
344
+ module Integer
345
+ # Returns a JSON string representation for this Integer number.
346
+ def to_json(*) to_s end
347
+ end
348
+
349
+ module Float
350
+ # Returns a JSON string representation for this Float number.
351
+ def to_json(state = nil, *)
352
+ case
353
+ when infinite?
354
+ if state && state.allow_nan?
355
+ to_s
356
+ else
357
+ raise GeneratorError, "#{self} not allowed in JSON"
358
+ end
359
+ when nan?
360
+ if state && state.allow_nan?
361
+ to_s
362
+ else
363
+ raise GeneratorError, "#{self} not allowed in JSON"
364
+ end
365
+ else
366
+ to_s
367
+ end
368
+ end
369
+ end
370
+
371
+ module String
372
+ if defined?(::Encoding)
373
+ # This string should be encoded with UTF-8 A call to this method
374
+ # returns a JSON string encoded with UTF16 big endian characters as
375
+ # \u????.
376
+ def to_json(*)
377
+ if encoding == ::Encoding::UTF_8
378
+ '"' << JSON.utf8_to_json(self) << '"'
379
+ else
380
+ string = encode(::Encoding::UTF_8)
381
+ '"' << JSON.utf8_to_json(string) << '"'
382
+ end
383
+ end
384
+ else
385
+ # This string should be encoded with UTF-8 A call to this method
386
+ # returns a JSON string encoded with UTF16 big endian characters as
387
+ # \u????.
388
+ def to_json(*)
389
+ '"' << JSON.utf8_to_json(self) << '"'
390
+ end
391
+ end
392
+
393
+ # Module that holds the extinding methods if, the String module is
394
+ # included.
395
+ module Extend
396
+ # Raw Strings are JSON Objects (the raw bytes are stored in an array for the
397
+ # key "raw"). The Ruby String can be created by this module method.
398
+ def json_create(o)
399
+ o['raw'].pack('C*')
400
+ end
401
+ end
402
+
403
+ # Extends _modul_ with the String::Extend module.
404
+ def self.included(modul)
405
+ modul.extend Extend
406
+ end
407
+
408
+ # This method creates a raw object hash, that can be nested into
409
+ # other data structures and will be unparsed as a raw string. This
410
+ # method should be used, if you want to convert raw strings to JSON
411
+ # instead of UTF-8 strings, e. g. binary data.
412
+ def to_json_raw_object
413
+ {
414
+ JSON.create_id => self.class.name,
415
+ 'raw' => self.unpack('C*'),
416
+ }
417
+ end
418
+
419
+ # This method creates a JSON text from the result of
420
+ # a call to to_json_raw_object of this String.
421
+ def to_json_raw(*args)
422
+ to_json_raw_object.to_json(*args)
423
+ end
424
+ end
425
+
426
+ module TrueClass
427
+ # Returns a JSON string for true: 'true'.
428
+ def to_json(*) 'true' end
429
+ end
430
+
431
+ module FalseClass
432
+ # Returns a JSON string for false: 'false'.
433
+ def to_json(*) 'false' end
434
+ end
435
+
436
+ module NilClass
437
+ # Returns a JSON string for nil: 'null'.
438
+ def to_json(*) 'null' end
439
+ end
440
+ end
441
+ end
442
+ end
443
+ end