turbostreamer 1.0 → 1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0f57b4f2c7ce7f14ba08eaae9087d07e8d69ae6d
4
- data.tar.gz: 7eb8046991d046191bc47378689739e971abdb80
3
+ metadata.gz: 69bc4c5ae74ca34c77d4efec5dcea7f3cc13121d
4
+ data.tar.gz: 8061f78d59db2cbab4fbab6903e690f499b63bbc
5
5
  SHA512:
6
- metadata.gz: e3abb1caae47743829462991a5d2f10798bc45c07ee5b51154424f522a08766520b9638d81bdbe84fda5b28208c5f72e7af148d28242ed63fa410cd7ff4a76f8
7
- data.tar.gz: 87118ef8372d08d696d2f9e2f3e703352ce04e3c9dbe5d30510a0e2edd05c3d8ab1f76ab8f66eda74007e1cd6de98e2d550f747b355a2cf65b5052444e8cd95c
6
+ metadata.gz: b921bb41799b13110dd30b3be833312f6a8049ee31dae19559ce7016b38b84b43bf304199172b10c932b0e8211ecd8574e2081100f109cf93d7ab27416fdf153
7
+ data.tar.gz: 1bf7d693f46fd09c78b2f7c3339acda1978a52356177ff0ddf1a1e680d4c5621cd9a1d7047ebd83d12354790b9f03237cf478f47e446303d3893c9b95eb833ab
@@ -0,0 +1,145 @@
1
+ require "oj"
2
+
3
+ class TurboStreamer
4
+ class OjEncoder
5
+
6
+ attr_reader :output
7
+
8
+ def initialize(io, options={})
9
+ @stack = []
10
+ @indexes = []
11
+
12
+ @options = {mode: :json}.merge(options)
13
+
14
+ @output = io
15
+ @stream_writer = ::Oj::StreamWriter.new(io, @options)
16
+ @write_comma_on_next_push = false
17
+ end
18
+
19
+ def key(k)
20
+ if @write_comma_on_next_push && (@stack.last == :array || @stack.last == :map)
21
+ @stream_writer.flush
22
+ @output.write(",".freeze)
23
+ @write_comma_on_next_push = false
24
+ end
25
+ @stream_writer.push_key(k)
26
+ end
27
+
28
+ def value(v)
29
+ if @stack.last == :array || @stack.last == :map
30
+ @indexes[-1] += 1
31
+
32
+ if @write_comma_on_next_push
33
+ @stream_writer.flush
34
+ @output.write(",".freeze)
35
+ @write_comma_on_next_push = false
36
+ end
37
+ end
38
+ @stream_writer.push_value(v)
39
+ end
40
+
41
+ def map_open
42
+ @stack << :map
43
+ @indexes << 0
44
+ if @write_comma_on_next_push
45
+ @stream_writer.flush
46
+ @output.write(",".freeze)
47
+ @write_comma_on_next_push = false
48
+ end
49
+ @stream_writer.push_object
50
+ end
51
+
52
+ def map_close
53
+ @indexes.pop
54
+ @stack.pop
55
+ @stream_writer.pop
56
+ end
57
+
58
+ def array_open
59
+ @stack << :array
60
+ @indexes << 0
61
+ if @write_comma_on_next_push
62
+ @stream_writer.flush
63
+ @output.write(",".freeze)
64
+ @write_comma_on_next_push = false
65
+ end
66
+ @stream_writer.push_array
67
+ end
68
+
69
+ def array_close
70
+ @indexes.pop
71
+ @stack.pop
72
+ @stream_writer.pop
73
+ end
74
+
75
+ def inject(string)
76
+ @stream_writer.flush
77
+
78
+ if @write_comma_on_next_push
79
+ @output.write(",".freeze)
80
+ @write_comma_on_next_push = false
81
+ end
82
+
83
+ if @stack.last == :array && !string.empty?
84
+ if @indexes.last > 0
85
+ self.output.write(",")
86
+ else
87
+ @write_comma_on_next_push = true
88
+ end
89
+ @indexes[-1] += 1
90
+ elsif @stack.last == :map && !string.empty?
91
+ if @indexes.last > 0
92
+ self.output.write(",")
93
+ else
94
+ @write_comma_on_next_push = true
95
+ end
96
+ @indexes[-1] += 1
97
+ end
98
+
99
+ self.output.write(string.sub(/\A,/, ''.freeze).chomp(",".freeze).strip)
100
+ end
101
+
102
+ def capture(to=nil)
103
+ @stream_writer.flush
104
+
105
+ old_writer = @stream_writer
106
+ old_output = @output
107
+ @indexes << 0
108
+
109
+ @output = (to || ::StringIO.new)
110
+ @stream_writer = ::Oj::StreamWriter.new(@output, @options)
111
+
112
+ # This is to prevent error from OJ streamer
113
+ # We will strip the brackets afterward
114
+ if @stack.last == :map
115
+ @stream_writer.push_object
116
+ elsif @stack.last == :array
117
+ @stream_writer.push_array
118
+ end
119
+
120
+ yield
121
+
122
+ @stream_writer.pop_all
123
+ @stream_writer.flush
124
+ result = output.string.sub(/\A,/, ''.freeze).chomp(",".freeze).strip
125
+
126
+ # Strip brackets as promised above
127
+ if @stack.last == :map
128
+ result = result.sub(/\A{/, ''.freeze).chomp("}".freeze)
129
+ elsif @stack.last == :array
130
+ result = result.sub(/\A\[/, ''.freeze).chomp("]".freeze)
131
+ end
132
+
133
+ result
134
+ ensure
135
+ @indexes.pop
136
+ @stream_writer = old_writer
137
+ @output = old_output
138
+ end
139
+
140
+ def flush
141
+ @stream_writer.flush
142
+ end
143
+
144
+ end
145
+ end
@@ -2,81 +2,82 @@ require 'wankel'
2
2
 
3
3
  class TurboStreamer
4
4
  class WankelEncoder < ::Wankel::StreamEncoder
5
-
5
+
6
6
  def initialize(io, options={})
7
7
  @stack = []
8
8
  @indexes = []
9
-
9
+
10
10
  super(io, {mode: :as_json}.merge(options))
11
11
  end
12
-
12
+
13
13
  def key(k)
14
14
  string(k)
15
15
  end
16
-
16
+
17
17
  def value(v)
18
18
  if @stack.last == :array || @stack.last == :map
19
19
  @indexes[-1] += 1
20
20
  end
21
21
  super
22
22
  end
23
-
23
+
24
24
  def map_open
25
25
  @stack << :map
26
26
  @indexes << 0
27
27
  super
28
28
  end
29
-
29
+
30
30
  def map_close
31
31
  @indexes.pop
32
32
  @stack.pop
33
33
  super
34
34
  end
35
-
35
+
36
36
  def array_open
37
37
  @stack << :array
38
38
  @indexes << 0
39
39
  super
40
40
  end
41
-
41
+
42
42
  def array_close
43
43
  @indexes.pop
44
44
  @stack.pop
45
45
  super
46
46
  end
47
-
47
+
48
48
  def inject(string)
49
49
  flush
50
50
 
51
51
  if @stack.last == :array
52
- self.output.write(',') if @indexes.last > 0
52
+ self.output.write(','.freeze) if @indexes.last > 0
53
53
  @indexes[-1] += 1
54
54
  elsif @stack.last == :map
55
- self.output.write(',') if @indexes.last > 0
55
+ self.output.write(','.freeze) if @indexes.last > 0
56
56
  capture do
57
- string("")
58
- string("")
57
+ string("".freeze)
58
+ string("".freeze)
59
59
  end
60
60
  @indexes[-1] += 1
61
61
  end
62
-
62
+
63
63
  self.output.write(string)
64
64
  end
65
-
65
+
66
66
  def capture(to=nil)
67
67
  flush
68
- old, to = self.output, to || ::StringIO.new
68
+ old_output = self.output
69
+ to = to || ::StringIO.new
69
70
  @indexes << 0
70
71
  self.output = to
71
-
72
+
72
73
  yield
73
-
74
+
74
75
  flush
75
- to.string.gsub(/\A,|,\Z/, '')
76
+ to.string.sub(/\A,/, ''.freeze).chomp(",".freeze)
76
77
  ensure
77
78
  @indexes.pop
78
- self.output = old
79
+ self.output = old_output
79
80
  end
80
-
81
+
81
82
  end
82
- end
83
+ end
@@ -1,3 +1,3 @@
1
1
  class TurboStreamer
2
- VERSION = '1.0'
3
- end
2
+ VERSION = '1.1.0'
3
+ end
data/lib/turbostreamer.rb CHANGED
@@ -2,49 +2,56 @@ require 'stringio'
2
2
  require 'turbostreamer/key_formatter'
3
3
 
4
4
  class TurboStreamer
5
-
5
+
6
6
  BLANK = ::Object.new
7
-
8
-
7
+
8
+
9
9
  ENCODERS = {
10
10
  json: {oj: 'Oj', wankel: 'Wankel'},
11
11
  msgpack: {msgpack: 'MessagePack'}
12
12
  }
13
-
13
+
14
14
  @@default_encoders = {}
15
15
  @@key_formatter = nil
16
16
 
17
17
  undef_method :==
18
18
  undef_method :equal?
19
-
19
+
20
20
  def self.encode(options = {}, &block)
21
21
  new(options, &block).target!
22
22
  end
23
-
23
+
24
24
  def initialize(options = {})
25
25
  @output_buffer = options[:output_buffer] || ::StringIO.new
26
- @encoder = options[:encoder] || TurboStreamer.default_encoder_for(options[:mime] || :json).new(@output_buffer)
26
+ @encoder = if options[:encoder].is_a?(Symbol)
27
+ TurboStreamer.get_encoder(options[:mime] || :json, options[:encoder])
28
+ elsif options[:encoder].nil?
29
+ TurboStreamer.default_encoder_for(options[:mime] || :json)
30
+ else
31
+ options[:encoder]
32
+ end
33
+ @encoder = @encoder.new(@output_buffer)
27
34
 
28
35
  @key_formatter = options.fetch(:key_formatter){ @@key_formatter ? @@key_formatter.clone : nil }
29
36
 
30
37
  yield self if ::Kernel.block_given?
31
38
  end
32
-
39
+
33
40
  def key!(key)
34
41
  @encoder.key(_key(key))
35
42
  end
36
-
43
+
37
44
  def value!(value)
38
45
  @encoder.value(value)
39
46
  end
40
-
47
+
41
48
  def object!(&block)
42
49
  @encoder.map_open
43
50
  _scope { block.call } if block
44
51
  @encoder.map_close
45
52
  end
46
-
47
- # Extracts the mentioned attributes or hash elements from the passed object
53
+
54
+ # Extracts the mentioned attributes or hash elements from the passed object
48
55
  # and turns them into a JSON object.
49
56
  #
50
57
  # Example:
@@ -63,8 +70,8 @@ class TurboStreamer
63
70
  extract!(object, *attributes)
64
71
  end
65
72
  end
66
-
67
- # Extracts the mentioned attributes or hash elements from the passed object
73
+
74
+ # Extracts the mentioned attributes or hash elements from the passed object
68
75
  # and turns them into attributes of the JSON.
69
76
  #
70
77
  # Example:
@@ -85,7 +92,7 @@ class TurboStreamer
85
92
  attributes.each{ |key| _set_value key, object.public_send(key) }
86
93
  end
87
94
  end
88
-
95
+
89
96
  # Turns the current element into an array and iterates over the passed
90
97
  # collection, adding each iteration as an element of the resulting array.
91
98
  #
@@ -98,7 +105,7 @@ class TurboStreamer
98
105
  #
99
106
  # [ { "name": David", "age": 32 }, { "name": Jamie", "age": 31 } ]
100
107
  #
101
- # It's generally only needed to use this method for top-level arrays. If you
108
+ # It's generally only needed to use this method for top-level arrays. If you
102
109
  # have named arrays, you can do:
103
110
  #
104
111
  # json.people(@people) do |person|
@@ -115,7 +122,7 @@ class TurboStreamer
115
122
  # [1,2,3]
116
123
  def array!(collection = BLANK, *attributes, &block)
117
124
  @encoder.array_open
118
-
125
+
119
126
  if _blank?(collection)
120
127
  _scope(&block) if block
121
128
  else
@@ -124,10 +131,10 @@ class TurboStreamer
124
131
 
125
132
  @encoder.array_close
126
133
  end
127
-
134
+
128
135
  def set!(key, value = BLANK, *args, &block)
129
136
  key!(key)
130
-
137
+
131
138
  if block
132
139
  if !_blank?(value)
133
140
  # json.comments @post.comments { |comment| ... }
@@ -197,16 +204,20 @@ class TurboStreamer
197
204
  def self.key_formatter=(formatter)
198
205
  @@key_formatter = formatter
199
206
  end
200
-
207
+
201
208
  def self.set_default_encoder(mime, encoder)
202
- @@default_encoders[mime] = encoder
209
+ if encoder.is_a?(Symbol)
210
+ @@default_encoders[mime] = get_encoder(mime, encoder)
211
+ else
212
+ @@default_encoders[mime] = encoder
213
+ end
203
214
  end
204
-
215
+
205
216
  def self.get_encoder(mime, key)
206
217
  require "turbostreamer/encoders/#{key}"
207
218
  Object.const_get("TurboStreamer::#{ENCODERS[mime][key]}Encoder")
208
219
  end
209
-
220
+
210
221
  def self.default_encoder_for(mime)
211
222
  if @@default_encoders[mime]
212
223
  @@default_encoders[mime]
@@ -215,7 +226,7 @@ class TurboStreamer
215
226
  next if !const_defined?(class_name)
216
227
  return get_encoder(mime, key)
217
228
  end
218
-
229
+
219
230
  ENCODERS[mime].to_a.find do |key, class_name|
220
231
  begin
221
232
  return get_encoder(mime, key)
@@ -223,7 +234,7 @@ class TurboStreamer
223
234
  next
224
235
  end
225
236
  end
226
-
237
+
227
238
  raise ArgumentError, "Could not find an adapter to use"
228
239
  end
229
240
  end
@@ -280,9 +291,9 @@ class TurboStreamer
280
291
  else
281
292
  object!{ extract!(value, *args) }
282
293
  end
283
-
294
+
284
295
  end
285
-
296
+
286
297
  # Encodes the current builder as JSON.
287
298
  def target!
288
299
  @encoder.flush
@@ -293,9 +304,9 @@ class TurboStreamer
293
304
  @encoder.output
294
305
  end
295
306
  end
296
-
307
+
297
308
  private
298
-
309
+
299
310
  def _write(key, value)
300
311
  @encoder.key(_key(key))
301
312
  @encoder.value(value)
@@ -313,7 +324,7 @@ class TurboStreamer
313
324
  def _capture(to=nil, &block)
314
325
  @encoder.capture(to, &block)
315
326
  end
316
-
327
+
317
328
  def _scope
318
329
  parent_formatter = @key_formatter
319
330
  yield
@@ -328,8 +339,8 @@ class TurboStreamer
328
339
  def _blank?(value=@attributes)
329
340
  BLANK == value
330
341
  end
331
-
342
+
332
343
  end
333
344
 
334
345
 
335
- require 'turbostreamer/railtie' if defined?(Rails)
346
+ require 'turbostreamer/railtie' if defined?(Rails)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: turbostreamer
3
3
  version: !ruby/object:Gem::Version
4
- version: '1.0'
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Bracy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-11-13 00:00:00.000000000 Z
11
+ date: 2017-12-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: oj
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: bundler
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -142,6 +156,34 @@ dependencies:
142
156
  - - ">="
143
157
  - !ruby/object:Gem::Version
144
158
  version: '0'
159
+ - !ruby/object:Gem::Dependency
160
+ name: analyzer
161
+ requirement: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
173
+ - !ruby/object:Gem::Dependency
174
+ name: jbuilder
175
+ requirement: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - ">="
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
180
+ type: :development
181
+ prerelease: false
182
+ version_requirements: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ version: '0'
145
187
  description:
146
188
  email:
147
189
  - jonbracy@gmail.com
@@ -155,6 +197,7 @@ files:
155
197
  - ext/actionview/streaming_template_renderer.rb
156
198
  - lib/turbostreamer.rb
157
199
  - lib/turbostreamer/dependency_tracker.rb
200
+ - lib/turbostreamer/encoders/oj.rb
158
201
  - lib/turbostreamer/encoders/wankel.rb
159
202
  - lib/turbostreamer/handler.rb
160
203
  - lib/turbostreamer/key_formatter.rb